home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / asmutil / asm_n_z.zip / SNOOP.ASM < prev    next >
Assembly Source File  |  1987-05-20  |  94KB  |  2,513 lines

  1. ; snoop.asm
  2. ;
  3. ; Written By Ray Smith
  4. ; Bix Name: rjsmith
  5. ; Copyright (c) 1987, Smith, Brittain & Associates. All rights reserved.
  6. ;
  7. ;
  8. ;*****************************************************************************
  9. ; Usage: snoop [/d] [/e] [/i] [/m] [/a] [/x] [/n]
  10. ;
  11. ;        where d = resident and installed device drivers
  12. ;              e = system equipment and configuration
  13. ;              i = Invars Table
  14. ;              m = Memory Control Blocks
  15. ;              a = all of the above
  16. ;              x = all of the above except /e
  17. ;              n = do Not pause the display, allowing the output to be 
  18. ;                  redirected to a file in a continuous stream.
  19. ;
  20. ;*****************************************************************************
  21. ;
  22. .8087
  23. cseg    segment para public 'code'
  24.     org     100h                     ; this will be a .com file
  25.     assume cs:cseg,ds:cseg           ; all seg regs point to start of PSP
  26. main    proc far
  27. ;
  28. begin:    jmp    entry                     ; go around the data
  29. ;
  30. ;***********************************************************************
  31. ;* Explanation of bit settings in byte "config_flag"
  32. ;***********************************************************************
  33. ;    
  34. ; Value      8   4   2   1     8   4   2   1
  35. ;        +-----------------+-----------------+
  36. ;  Bit   |                 |                 |
  37. ; Number |  07  06  05  04 |  03  02  01  00 |
  38. ;        |                 |                 |
  39. ;        +-----------------+----------------------------------------+
  40. ;     01 |   |   |   |   |     |   |   |   1 = PC/AT Class Machine  |
  41. ;     02 |   |   |   |   |     |   |   1 = Enhanced BIOS Present    |         
  42. ;     04 |   |   |   |   |     |   1 = Enhanced Keyboard Attached   |     
  43. ;     08 |   |   |   |   |     1 = Compaq DeskPro 386 or klone      | 
  44. ;     10 |   |   |   |   1 = PC/XT Class Machine                    | 
  45. ;     20 |   |   |   1 = PC Class Machine                           |
  46. ;     40 |   |   1 = PC Convertible                                 |
  47. ;     80 |   1 = PC/XT 089                                          |
  48. ;        +----------------------------------------------------------+
  49. ;
  50. ;
  51. display_flag db 0h
  52. config_flag  db 0h
  53. equ_flag     db 0h
  54. inv_flag     db 0h
  55. drv_flag     db 0h
  56. pse_flag     db 0h
  57. mem_flag     db 0h
  58. cpu_flag     db 0h
  59. ps2_flag     db 0h
  60. sys_flag     db 0h
  61. env_flag     db 0h
  62. psp_flag     db 0h
  63. tsr_flag     db 0h
  64. mt_flag      db 0h
  65. data_flag    db 0h
  66. switchar     db 2Fh   ; "/" for command line switches
  67. pathchar     db 5Ch   ; "\" for path name delimiter
  68. switch_err   db 0h 
  69. scan_code    db 44h    
  70. loop_count   dw 0h
  71. arg_cnt      dw 0h
  72. argc         db 0h
  73. optcnt       db 0h
  74. portcnt      db 0h
  75. total_pages  dw 0h
  76. avail_pages  dw 0h
  77. firstenv     db 01h
  78. firstpsp     db 01h
  79. firstmcb     db 01h
  80. firstsys     db 01h
  81. one          db 01h
  82. linecnt      db 0h
  83. de_allocmsg  db 'Deallocated$'  
  84. systype      db 'DOS $'
  85. psptype      db 'PSP $'
  86. envtype      db 'ENV $'
  87. datatype     db 'DATA$'
  88. mttype       db 'Unkn$'
  89. lastdpb      db 'Chain Ends$'
  90. notread      db 'nr$'     ; drive was not read
  91. dos_vers     dw 0h
  92. emm_vers     db 0h
  93. rom_flag db     0FFh
  94. get_key  db     0h        ; default BIOS Int 16h function to read a key
  95. avail_c  db     01h       ; default BIOS Int 16h function to check avail char
  96. get_sts  db     02h       ; default BIOS Int 16h function to check shift status
  97. control  dw     0h        ; save 80x87 control word
  98. sav_code db     0h
  99. sav_addr dw     0h
  100. sav_off  dw     0h
  101. invar_seg dw    0h
  102. invar_off dw    0h
  103. dpb_seg  dw     0h
  104. dpb_off  dw     0h
  105. sav_name db     '             '
  106.          db     '$'
  107. type_drv dw     0h
  108. devh_seg dw     0h        ; segment address NUL device driver
  109. devh_off dw     0h        ; offset  address NUL device driver
  110. next_seg dw     0h        ; next seg addr
  111. next_off dw     0h        ; next off addr
  112. colon    db     ':'
  113. emm_name db     'EMMXXXX0' ; Guaranteed emm device driver file name
  114. blank    db     20h
  115. ourcopy  db     0Dh,0Ah,' Copyright (c) 1987 Smith, Brittain & Associates. '
  116.          db     'All Rights Reserved.$'
  117. mcbseg   dw     0h
  118. filename db '        $'
  119. dataname db '        $'
  120.          db     'Written By Raymond J. Smith'
  121. msg1     db    0Dh,0Ah,' Machine is an IBM PC/AT or AT klone $'
  122. msg1A     db    0Dh,0Ah,' Machine is an IBM PC/AT Model 339   $'
  123. msg1B     db    0Dh,0Ah,' Machine is an IBM PC/AT Model 239   $'
  124. msg1C     db    0Dh,0Ah,' Machine is an IBM PC/AT Model 099   $'
  125. msg1D     db    0Dh,0Ah,' Machine is a Compaq Dekspro 386 or compatible$'
  126. msg1E     db    0Dh,0Ah,' Machine is an IBM Personal System/2 Model 30$'
  127. msg1F     db    0Dh,0Ah,' Machine is an IBM Personal System/2 Model 50$'
  128. msg1G     db    0Dh,0Ah,' Machine is an IBM Personal System/2 Model 60$'
  129. msg1H     db    0Dh,0Ah,' Machine is an IBM Personal System/2 Model 80$'
  130. msg2     db    0Dh,0Ah,'         Enhanced BIOS is present $'
  131. msg3     db    0Dh,0Ah,'         Enhanced Keyboard is attached  $'
  132. msg4     db    0Dh,0Ah,' Machine ID byte contains code ==> $'
  133. msg5     db    0Dh,0Ah,'         No Enhanced BIOS is present $'
  134. msg6     db    0Dh,0Ah,'         No Enhanced Keyboard is attached  $'
  135. msg7     db    0Dh,0Ah,'                           Press any key to continue... $'
  136. msg9     db    0Dh,0Ah,'         EGA is active adapter $'
  137. msg10     db    0Dh,0Ah,'         EGA is active and is monochrome $'
  138. msg11     db    0Dh,0Ah,'         EGA is not active, a MDA or Hercules card is active $'
  139. msg12     db    0Dh,0Ah,'         EGA is not active, a CGA is active $'
  140. msg14    db    0Dh,0Ah,'         EGA has 64kb graphics memory installed  $'
  141. msg15    db    0Dh,0Ah,'         EGA has 128kb graphics memory installed  $'
  142. msg16    db    0Dh,0Ah,'         EGA has 192kb graphics memory installed  $'
  143. msg17    db    0Dh,0Ah,'         EGA has 256kb graphics memory installed  $'
  144. msg18    db    0Dh,0Ah,'         Enhanced Color Display is attached $'
  145. msg18A   db    0Dh,0Ah,'         Enhanced Color Display in Color Graphics mode is attached $'
  146. msg19    db    0Dh,0Ah,'         Normal Color Display is attached $'
  147. msg19A   db    0Dh,0Ah,'         CGA is active$'
  148. msg20    db    0Dh,0Ah,'         Monochrome Display is active$'
  149. msg21     db    0Dh,0Ah,' Machine is an IBM PC/XT or XT klone $'
  150. msg22     db    0Dh,0Ah,' Machine is an IBM PC or PC klone $'
  151. msg23     db    0Dh,0Ah,' Machine is an IBM PC convertible $'
  152. msg24     db    0Dh,0Ah,' Machine is a PC/XT Model 089 $'
  153. msg25     db    0Dh,0Ah,' Machine is a PC/XT Model 286 $'    
  154. msg26     db    0Dh,0Ah,'         EGA switches improperly set $'
  155. msg27    db    0Dh,0Ah,'         8087 is installed $'
  156. msg28    db    0Dh,0Ah,'         80287 is installed $'
  157. msg29    db    0Dh,0Ah,'         no NDP is installed$'
  158. msg30    db    ' exTEnded memory installed$',0Dh,0Ah
  159. msg31    db    ' exPAnded memory installed$'
  160. msg31A   db     ' total EMS pages$'
  161. msg31B   db     ' available EMS pages$'
  162. msg31C   db     0Dh,0Ah,'         EMM Version: $'
  163. msg32    db    0Dh,0Ah,'         no$'
  164. msg33    db    0Dh,0Ah,'         System is operating under DOS Version $'
  165. msg33A   db     0Dh,0Ah,'         Switch character currently in effect is $'
  166. msg33B   db     0Dh,0Ah,'         DOS Int 21h Function 37h not responding$'
  167. msg34    db    ' is installed$'
  168. msg35    db    '3.00$'
  169. msg36    db    '3.10$'
  170. msg37    db    '3.20$'
  171. msg37A   db    '3.30$'
  172. msg37B   db    '3.40$'
  173. msg38    db    '2.00$'
  174. msg39    db    '2.10$'
  175. msg40    db    'is unknown$'
  176. msg41    db    'kb$'
  177. msg42    db    ' base memory installed$',0Dh,0Ah
  178. msg43    db    ' OR the EMM is not installed$'
  179. msg44    db    'LPT1: $'
  180. msg45    db    'LPT2: $'
  181. msg46    db    'LPT3: $'
  182. msg47    db    'COM1: $'
  183. msg48    db    'COM2: $'
  184. msg48A   db    'COM3: $'
  185. msg48B   db    'COM4: $'
  186. msg49    db    'No Parallel Ports active$'
  187. msg50    db    'No Serial Ports active$'
  188. msg98    db    '2.x$'
  189. msg99    db    '3.x$'
  190. copyrite db     'ROM BIOS Copyright ==> $'
  191. biosdate db     'ROM BIOS dated $'
  192. egacopy  db     'EGA BIOS Copyright ==> $'
  193. egadate  db     'EGA BIOS dated $'
  194. baddrv   db    'Corrupted EMM Driver $'
  195. badbrd   db    'Malfunction in exPAnded memory hardware$'
  196. romid    db    'Adapter ROM signature found at segment $'
  197. noroms   db    'No adapter ROMs detected $'
  198. newline  db    0Dh,0Ah,'$'
  199. indent   db     '         $'
  200. rom_sig  dw     0AA55h
  201. tbuff    db     255 dup('$')
  202. char_dev db     'Char   $'
  203. blk_dev  db     'Block  $'
  204. clk_dev  db     'Clock  $'
  205. cmndmsg  db     'COMMAND $'
  206. sysmsg   db     'System  $'
  207. freemsg  db     'Free    $'
  208. mtblkmsg db     '<Empty> $'
  209. unknmsg  db     'Unknown $'
  210. envmsg   db     'Process Env  $'
  211. mastenv  db     'Master Env   $'
  212. tsrmsg   db     'TSR          $'
  213. resdmsg  db     'Resident part$'
  214. datamsg  db     'Process Data $'
  215. thismsg  db     'Transient    $'
  216. drvmsg   db     'Dev Drvs, etc$'
  217. space1   db     ' $'
  218. space2   db     '  $'
  219. space3   db     '   $'
  220. space4   db     '    $'   
  221. space5   db     '     $'
  222. space6   db     '      $'
  223. space7   db     '       $'
  224. space8   db     '        $'
  225. space9   db     '         $'
  226. space10  db     '          $'
  227. space11  db     '           $'
  228. space12  db     '            $'
  229. space13  db     '             $'
  230. space14  db     '              $'
  231. scr1     db 0Dh,0Ah,'                     Partial Contents of DOS "Invar" Table'
  232.          db 0Dh,0Ah,' '  
  233.          db 0Dh,0Ah,'   Invar        First      1st Dir      Size of    Drive/Directory  DOS "Busy"'
  234.          db 0Dh,0Ah,'   Table      DPB Table     Buffer      1 Cache         Table         Flag'
  235.          db 0Dh,0Ah,' Seg : Off    Seg : Off    Seg : Off    Buffer        Seg : Off     Seg : Off'
  236.          db 0Dh,0Ah,' ---------    ---------    ---------    -------       ---------     --------- $'
  237. scr1A    db 0Dh,0Ah,'                     Contents of DPB Table By Drive'
  238.      db 0Dh,0Ah,'                                                        Dev Drvr      Next DPB'
  239.      db 0Dh,0Ah,'Drv DU BPC  SPC   RS  CF  MDE   FUS   TCC   SIF  FDS    Hdr Addr  MD   Address'
  240.      db 0Dh,0Ah,'--  -- ---- ---  ---- --  ----  ----  ----  ---  ----  ---------  --  ---------$'
  241. scr2     db 0Dh,0Ah,'                       Installed Device Drivers'
  242.          db 0Dh,0Ah,'       Name or      Header Address   Entry Points               DOS'
  243.          db 0Dh,0Ah,'Type   # Units        Seg : Off      Strat  Interpt   Attrib  Version'
  244.          db 0Dh,0Ah,'----------------------------------------------------------------------------$'
  245. scr3     db 0Dh,0Ah,'                             Memory  Allocation '
  246.          db 0Dh,0Ah,' '  
  247.          db 0Dh,0Ah,'MCB   Points Paras                                         Hooked'
  248.          db 0Dh,0Ah,'Addr  To Blk Alloc Type Owner     Comment       Cmnd Line  Vectors'
  249.          db 0Dh,0Ah,'----  ----   ----  ---- --------  -----------   ---------  -------------------$'
  250. cnt      dw 00h
  251. vectcnt  dw 00h
  252. blk_beg  dw 00h
  253. blk_end  dw 00h
  254. usemsg   db 0Dh,0Ah,' Usage: snoop [/d] [/e] [/i] [/m] [/a] [/n]',0Dh,0Ah
  255.          db 0Dh,0Ah
  256.          db 0Dh,0Ah,'        where d = list device drivers'
  257.          db 0Dh,0Ah,'              e = list equipment'
  258.          db 0Dh,0Ah,'              i = list Invars Table and DPBs'
  259.          db 0Dh,0Ah,'              m = list Memory Control Blocks'
  260.          db 0Dh,0Ah,'              a = list all of the above'
  261.          db 0Dh,0Ah,'              n = do Not pause the display'
  262.          db 0Dh,0Ah,'              x = list all of the above except e'
  263.          db 0Dh,0Ah,'                  (for non-IBM BIOS compatible machines)$'
  264. ;
  265. ;***********************************************************************
  266. ;* Beginning of Code Seg
  267. ;***********************************************************************
  268. entry:
  269.         call switch_char                 ; go see what they're using for paths
  270.         mov  switch_err,al               ; check for error and store for later 
  271.         call chk_switch                  ; get our command line switches
  272.         mov  ah,30h             ; get dos ver num
  273.     int  21h             ; go do it
  274.            xchg ah,al             ; turn it around
  275.         mov  dos_vers,ax                 ; need for NUL device driver location
  276.     cmp  ax,0200h                 ; 2.00 or greater?
  277.     jae  oz_ok
  278. bad_oz:
  279.     jmp  quit                        ; need 2.0 or greater
  280. oz_ok:
  281.     mov  dx,offset ourcopy         ; display our copyright message
  282.         call dostty
  283.     mov  dx,offset newline         
  284.         call dostty
  285.         cmp  equ_flag,0FFh               ; switch set for equipment list?
  286.         je   equip_tests                 ; yes
  287.         jmp  invar_chk                   ; no - bypass equipment list
  288.  
  289. equip_tests:
  290.         clc                              ; clear the carry flag for error rtn
  291.         mov  ah,0C0h                     ; get configuration parameters
  292.         int  15h                         ; avaialable on AT class machines only
  293.         sti                              ; int 15h does not reenable interrupts
  294.         jc   is_old                      ; it's a PC
  295.         cmp  ah,80h                      ; return value if original PC
  296.         je   is_old                      ; 86h is returned on all PS/2 models
  297.         cmp  ah,86h                      ; return value if not new machine
  298.         jne  is_new                      ; 86h is returned on all PS/2 models
  299. is_old:
  300.         jmp  test_more                   ; it's either a PS/2 or PC PC/XT class
  301. is_new:                                  ; determine machine type
  302.         cmp  ax,00FFh                    ; return value if  PS/2
  303.         jne  not_new_mod                 ; 
  304.         call chk_ps2
  305.         cmp  ps2_flag,0h
  306.         je   not_new_mod                 ; 
  307.         jmp  at_tests
  308. not_new_mod:
  309.         cmp  byte ptr es:[bx+2],0FCh     ; AT class machine ID
  310.         je   chk_339
  311.         jmp  test_more  
  312.  
  313. chk_339:
  314.         cmp  byte ptr es:[bx+3],01h      ; check sub-model type byte
  315.         je   is_339                      ; 1 means IBM AT/339 or Compaq 386
  316.         cmp  byte ptr es:[bx+3],02h      ; check sub-model type byte
  317.         jne  next_one
  318.         jmp  xt_286                      ; a 2 means it's an IBM XT/286
  319. next_one:
  320.         cmp  byte ptr es:[bx+3],0h       ; check sub-model type byte
  321.         je   is_239                      ; 0 means it's an IBM AT/239 or 099
  322.         jmp  test_more                   ; (note:AT/239 has rom 06/10/85)
  323.  
  324. is_339:                                  ; mach id byte is FCh - means little
  325.         call chk_cpu                     ; see if 386 or 286 cpu
  326.     cmp  byte ptr cs:cpu_flag,03h    ; is it a 386 cpu?
  327.         je   is_386                      ; 
  328. is_286:                                  ; it's a 286 cpu
  329.     or   byte ptr cs:config_flag,01h ; indicate PC/AT
  330.     mov  dx,offset msg1A         ; AT class message
  331.         call dostty
  332.         jmp  at_tests
  333. is_386:
  334.     or   byte ptr cs:config_flag,09h ; indicate PC/AT class & 386 class
  335.     mov  dx,offset msg1D         ; Compaq DeskPro 386 Class message
  336.         call dostty
  337.         jmp  at_tests
  338.  
  339. is_239:
  340.     or   byte ptr cs:config_flag,01h ; indicate PC/AT
  341.         cmp  byte ptr es:[bx+4],0h       ; check bios level byte
  342.         je   is_099                      ; 0 means it's an IBM AT/099
  343.         cmp  byte ptr es:[bx+4],01       ; check bios level byte
  344.         jne  test_more                   ; 1 means it's an IBM AT/239
  345.     mov  dx,offset msg1B         ; Einen Klonen Machinen message
  346.         call dostty                      ; if all tests fail, assume klone
  347.         jmp  at_tests                    ; test for AT type stuff
  348. is_099:
  349.     mov  dx,offset msg1C         ; original 6 mHz AT
  350.         call dostty
  351.         jmp  at_tests
  352.  
  353. ;***********************************************************************
  354. ;* Determine Machine Type for non_AT type machines.                    *
  355. ;***********************************************************************
  356. test_more:        
  357.     mov  ax,0F000h                 ; seg address of rom bios
  358.     mov  es,ax                       ; establish addressibility
  359.     mov  ax,word ptr es:[0FFFEh]     ; offset of rom bios machine id byte
  360.         call chk_mod30                   ; see if PS/2 Model 30 first 
  361.         cmp  ps2_flag,30h                ; is it a PS/2 model 30?
  362.         jne  not_a_30                    ; if greater, is model 50/60/80
  363.         jmp  chk_mem
  364. not_a_30:
  365.     cmp  al,0FCh                   ; not PS/2: PC/AT? Compaq 386? XT/286?
  366.         je   at_ok                          ; 
  367.     jmp  not_at             ; it's not PS/2 or AT class
  368. at_ok:
  369.     or   byte ptr cs:config_flag,01h ; indicate PC/AT
  370.     mov  dx,offset msg1         ; 
  371.         call dostty
  372.         jmp  at_tests
  373.  
  374. xt_286:
  375.     or   byte ptr cs:config_flag,01h ; indicate PC/AT class machine
  376.     mov  dx,offset msg25         ; 
  377.         call dostty
  378.  
  379. ;***********************************************************************
  380. ;* These tests are applicable to AT class machines only.               *
  381. ;***********************************************************************
  382. ;
  383. at_tests:
  384.                                          ; test for base memory 
  385.         int  12h                         ; BIOS int 12h returns memory size
  386.         push ax                          ; this is safe on an AT
  387.     mov  dx,offset newline         
  388.         call dostty
  389.     mov  dx,offset indent          
  390.         call dostty
  391.         pop  dx
  392.         call dec16out
  393.     mov  dx,offset msg41         ; kb
  394.         call dostty
  395.     mov  dx,offset msg42         ; bytes
  396.         call dostty
  397. ;
  398. ;****************************************************************************
  399. ;* Test for presence and amount of exTEnded memory (AT class machines only) *
  400. ;****************************************************************************
  401.         mov  ax,8800h
  402.         int  15h
  403.         cmp  ax,0h
  404.         je   noexten
  405.         push ax
  406.     mov  dx,offset newline         
  407.         call dostty
  408.     mov  dx,offset indent          
  409.         call dostty
  410.         pop  dx
  411.         call dec16out                    ; convert binary to decimal & display
  412.     mov  dx,offset msg41         ; kb
  413.         call dostty
  414.         jmp  extend
  415. noexten:
  416.     mov  dx,offset msg32         ; no exTEnded memory installed
  417.         call dostty
  418.     mov  dx,offset msg30
  419.         call dostty
  420.         jmp  chk_emm                     ; go see if exPAnded memory installed
  421.  
  422. extend:
  423.     mov  dx,offset msg30         ; exTEnded memory is installed
  424.         call dostty
  425.         jmp  chk_emm                     ; go see if exPAnded memory installed
  426. ;
  427. ;***********************************************************************
  428. ;* Test for machine type if not AT class.                              *
  429. ;***********************************************************************
  430. not_at:
  431.         cmp  ps2_flag,30h                ; is this a PS/2 Model 30?
  432.         je   chk_mem                     ; if yes, go right to mem chk
  433.     cmp  al,0FEh                   ; is this a PC/XT ?
  434.     jne   not_xt             ; set flag if it is, branch if not
  435.     or   byte ptr cs:config_flag,10h ; indicate PC/XT
  436.     mov  dx,offset msg21         ; 
  437.         call dostty
  438.         jmp  chk_mem
  439. not_xt:
  440.     cmp  al,0FFh                   ; is this a PC ?
  441.     jne   not_pc             ; set flag if it is, branch if not
  442.     or   byte ptr cs:config_flag,20h ; indicate PC
  443.     mov  dx,offset msg22         ; 
  444.         call dostty
  445.         jmp  chk_mem
  446. not_pc:
  447.     cmp  al,0F9h                   ; is this a PC Convertible?
  448.     jne   xt_089             ; set flag if it is, branch if not
  449.     or   byte ptr cs:config_flag,40h ; indicate PC Convertible
  450.     mov  dx,offset msg23         ; 
  451.         call dostty
  452.         jmp  chk_mem
  453.  
  454. xt_089:
  455.     cmp  al,0FBh                   ; is this a new PC/XT-089? 
  456.     jne   unk_id             ; set flag if it is, branch if not
  457.     or   byte ptr cs:config_flag,80h ; indicate PC/XT-089 
  458.     mov  dx,offset msg24         ; 
  459.         call dostty
  460.         jmp  chk_mem
  461.  
  462. unk_id:
  463.         mov  dx,offset msg4         ; don't recognize this Klone 
  464.         call dostty
  465.         mov  sav_code,al                 ; display the actual machine ID byte
  466.     mov  cx,1                     ; count of bytes to display
  467.     lea  bx,[sav_code]
  468.         call show_bytes
  469. ;
  470. ;***********************************************************************
  471. ; Test for amount of conventional memory.                              *
  472. ;***********************************************************************
  473. chk_mem:                                 ; test for main memory if not AT class 
  474.                                          ;  machine
  475.         int  12h                         ; BIOS int 12h returns memory size
  476.         push ax                          ; risky: only returns switch settings
  477.     mov  dx,offset newline         
  478.         call dostty
  479.     mov  dx,offset indent          
  480.         call dostty
  481.         pop  dx
  482.         call dec16out
  483.     mov  dx,offset msg41         ; kb
  484.         call dostty
  485.     mov  dx,offset msg42         ; bytes
  486.         call dostty
  487. ;
  488. ;***********************************************************************
  489. ;* Test for presence and amount of LIM/EMS (exPAnded) memory
  490. ;***********************************************************************
  491. ;
  492. chk_emm:
  493.         mov  ah,35h
  494.         mov  al,67h
  495.         int  21h
  496.         mov  di,0Ah
  497.         push cs
  498.         pop  ds
  499.         mov  si,offset emm_name          ; guaranteed device driver name
  500.         mov  cx,8                        ; length of file name
  501.         cld
  502.         repz cmpsb
  503.         jz   chk_ems_hardware
  504.         jmp  no_emm
  505. ;***********************************************************************
  506. ;* Find out if hardware is functional using Int 67h fcn 40h
  507. ;***********************************************************************
  508. chk_ems_hardware:
  509.         mov  ah,40h                      ;
  510.         int  67h
  511.         cmp  ah,0h                       ; zero return code means all ok
  512.         je   emm_ok
  513.         cmp  ah,80h                      ;
  514.         je   bad_drv
  515. bad_hard:
  516.     mov  dx,offset newline         ;
  517.         call dostty
  518.     mov  dx,offset indent          
  519.         call dostty
  520.     mov  dx,offset badbrd            ; bad emm hardware
  521.         call dostty
  522.         jmp  chk_bios
  523. bad_drv:
  524.     mov  dx,offset newline         
  525.         call dostty
  526.     mov  dx,offset indent          
  527.         call dostty
  528.     mov  dx,offset baddrv            ; bad emm driver image
  529.         call dostty
  530.         jmp  chk_bios
  531. ;
  532. ;***********************************************************************
  533. ;* Find out how many pages present/available using Int 67h fcn 03h
  534. ;***********************************************************************
  535. emm_ok:
  536.     mov  dx,offset newline         
  537.         call dostty
  538.     mov  dx,offset indent          
  539.         call dostty
  540.         mov  ah,42h                      ; get number of pages
  541.         int  67h
  542.         or   ah,ah
  543.         jz   no_err
  544.                                          ; put error messages here
  545.         jmp  chk_bios
  546. no_err:
  547.         mov  word ptr total_pages,dx     ; dx holds total number of 16kb pages
  548.         mov  word ptr avail_pages,bx     ; bx holds number of available pages
  549.         call dec16out                    ; display it
  550.     mov  dx,offset msg31A            ; 
  551.         call dostty
  552.     mov  dx,offset newline         
  553.         call dostty
  554.     mov  dx,offset indent          
  555.         call dostty
  556.         mov  dx,word ptr avail_pages
  557.         call dec16out                    ; display it
  558.     mov  dx,offset msg31B            ; 
  559.         call dostty
  560. ;
  561. ;***********************************************************************
  562. ;* Find out the EMS version using Int 67h fcn 07h
  563. ;***********************************************************************
  564. ;
  565.         mov  ah,46h                      ; get emm version
  566.         int  67h                         ; al = version # in BCD
  567.         mov  byte ptr emm_vers,al        ; Major revision in upper 4 bits
  568.                                          ; Minor revision in lower 4 bits
  569.     mov  dx,offset msg31C            ; 
  570.         call dostty
  571.         mov  al,byte ptr emm_vers
  572.         and  ax,00F0h                    ; isolate major ver #
  573.         mov  cl,4                        ; shift to low bits
  574.         shr  ax,cl                 
  575.         add  al,30h                      ; make it ascii
  576.         mov  dl,al                       ; set it up for stdout
  577.         call stdout                      ; display major version #
  578.         mov  dl,2Eh
  579.         call stdout                      ; display a period
  580.         mov  al,byte ptr emm_vers        ; get emm version
  581.         and  ax,000Fh                    ; isolate minor version
  582.         add  al,30h                      ; make it ascii
  583.         mov  dl,al                       ; set it up for stdout
  584.         call stdout                      ; display minor version #
  585.         jmp  chk_bios
  586.  
  587. no_emm:
  588.     mov  dx,offset msg32          ; no exPAnded memory found...
  589.         call dostty
  590.     mov  dx,offset msg31
  591.         call dostty
  592.     mov  dx,offset msg43             ; ...or the emm not installed
  593.         call dostty
  594. ;
  595. ;***********************************************************************
  596. ;* display copyright and rom release date and test for enhanced BIOS   *
  597. ;***********************************************************************
  598. chk_bios:
  599.                                          ; display copyright slug
  600.     mov  dx,offset newline         
  601.         call dostty
  602.     mov  dx,offset indent          
  603.         call dostty
  604.     mov  dx,offset copyrite         ; copyright header string
  605.         call dostty
  606.         cld
  607.         push es
  608.         push ds
  609.         push ds
  610.         pop  es                          ; destination string address in es:di
  611.         mov  ax,0F000h                   ; source string address in ds:si
  612.         mov  ds,ax                       ; ...location of IBM AT copyright
  613.         xor  ax,ax
  614.         mov  cx,10h                      ; count of words in copyright
  615.     test byte ptr cs:config_flag,10h ; is this an older PC/XT?
  616.         jz   getcopy
  617.         mov  ax,0E000h                   ; IBM XT copyright is higher up in rom
  618.         mov  cx,0Bh                      ; count of words (XT is shorter)
  619. getcopy:
  620.         mov  bx,cx                       ;
  621.         shl  bx,1                        ; multiply by 2 to get offset of 
  622.         mov  si,ax                       ; terminator character in dest string
  623.         mov  di,offset es:tbuff
  624.         rep  movsw
  625.         pop  ds
  626.         pop  es
  627.         mov  byte ptr tbuff+[bx],'$'    ; insert terminator
  628.         mov  bx, offset tbuff
  629. scan:
  630.         cmp  byte ptr[bx],'$'           ; are we done?
  631.         je   end_scan                   ; go display it
  632.         cmp  byte ptr[bx],' '           ; less than a space?
  633.         jb   hide_it                    ;
  634.         cmp  byte ptr[bx],'~'           ; greater than a tilde
  635.         jna  bump_bx                    ; if not it's printable
  636.         
  637. hide_it:
  638.         mov  byte ptr[bx],20h           ; make nonsense characters a space
  639. bump_bx:
  640.         inc  bx                         ; increment the address
  641.         jmp  scan                       ; go do it again
  642. end_scan:
  643.         mov  dx,offset tbuff            ; 
  644.         call dostty
  645.         push es
  646.         push ds
  647.         push ds
  648.         pop  es                          ; destination string address in es:di
  649.     mov  dx,offset newline         
  650.         call dostty
  651.     mov  dx,offset indent          
  652.         call dostty
  653.     mov  dx,offset biosdate         ; date header
  654.         call dostty
  655.         mov  ax,0F000h                   ; source string address in ds:si
  656.         mov  ds,ax
  657.         mov  ax,0FFF5h                    ;offset of rom release date
  658.         mov  si,ax
  659.         mov  di,offset es:tbuff
  660.         mov  cx,04h                      ; count of words
  661.         rep  movsw
  662.         pop  ds
  663.         pop  es
  664.         mov  byte ptr tbuff[08h],'$'     ; insert string terminator
  665.         mov  dx,offset tbuff             
  666.         call dostty
  667.                                          ; check for enhanced bios
  668.         mov  ah,2                        ; get shift status (old function)
  669.         int  16h                         ;  
  670.         mov  bl,al                       ; Save shift status
  671.         not  al                          ; change al (invert all bits)
  672.         mov  ah,12h                      ; new BIOS extended shift status
  673.         int  16h                         ; 
  674.         cmp  al,bl                       ; is result the same from both calls?
  675.         jne  next1                       ; if not, this is not enhanced BIOS
  676.         or   byte ptr cs:config_flag,02h ; indicate enhanced BIOS present
  677.     mov  ax,40h                 ; seg address of BIOS data area
  678.     mov  es,ax                       ; establish addressibility
  679.     mov  al,byte ptr es:[96h]     ; offset of BIOS @KB_FLAG_3 byte
  680.     test al,10h                   ; is enhanced keyboard attached?
  681.     jz   next1               ; set flag if it is, branch if not
  682.         or   byte ptr cs:config_flag,04h ; indicate enhanced keyboard attached
  683.         test byte ptr cs:config_flag,06h ; could be new XTs with enhanced BIOS 
  684.     jz   next1                       ; branch if not
  685.     add  get_key,10h                 ; if new bios...
  686.     add  avail_c,10h                 ; ...and new keyboard...
  687.     add  get_sts,10h                 ; ...add 10h to get extended functions
  688.  
  689. next1:
  690.         test byte ptr cs:config_flag,02h ; is enhanced BIOS present?
  691.     jz   old_bios             ; branch if not
  692.     mov  dx,offset msg2
  693.         call dostty
  694.         jmp  new_bios
  695. old_bios:
  696.     mov  dx,offset msg5
  697.         call dostty
  698. new_bios:
  699.         test byte ptr cs:config_flag,04h ; is enhanced keyboard present?
  700.     jz   not_enhanced            ; branch if not
  701.     mov  dx,offset msg3         ; 
  702.         call dostty
  703.         mov  scan_code,86h               ; ascii code for F12
  704.     jmp  scan_rom
  705. not_enhanced:
  706.     mov  dx,offset msg6
  707.         call dostty
  708.  
  709. ;***********************************************************************
  710. ;* Scan ROM for BIOS IDs...
  711. ;***********************************************************************
  712. scan_rom:
  713.         mov  dx,0C000h                   ; start point for rom signature scan
  714.         mov  di,word ptr rom_sig         ; rom signature is 55 AA hex
  715. scan_loop:
  716.         mov  es,dx 
  717.         xor  bx,bx                       ; offset zero
  718.         mov  ax,es:[bx]                  ; 
  719.         cmp  ax,di                       ; equal to 55 AA ?
  720.         jnz  next_blk                    ; if no, go increment block address
  721.         mov  ax,es                       ; get segment address for display
  722.         push dx
  723.     mov  dx,offset newline         
  724.         call dostty
  725.     mov  dx,offset indent          
  726.         call dostty
  727.     mov  dx,offset romid             ; ROM detected message
  728.         call dostty
  729.         call disp_hex
  730.         mov  al,'h'
  731.         call stdout
  732.         mov  rom_flag,0h                 ; indicate an adapter ROM was found
  733.         pop  dx
  734. next_blk:
  735.         add  dx,80h                      ; point to next 2k address
  736. chk_addr:
  737.         cmp  dx,0F600h                   ; end of addresses where ROMs can be?
  738.         jl   scan_loop                   ; search for more if not
  739. no_roms:
  740.         cmp  rom_flag,0h                 ; was an adapter ROM found?
  741.         je   end_rom                     ; yes? bypass message
  742.     mov  dx,offset newline         
  743.         call dostty
  744.     mov  dx,offset indent          
  745.         call dostty
  746.     mov  dx,offset noroms            ; no ROMs detected
  747.         call dostty
  748. end_rom:
  749. ;
  750. ;***********************************************************************
  751. ;* Check active display and adapter
  752. ;***********************************************************************
  753. ;
  754. chkdisp:                                 ; check for presence of an EGA first
  755.         mov  bx, 0FF10h                  ; see if EGA responds
  756.         mov  ah, 12h
  757.         int  10h
  758.         test bh, 0FEh                    ; bl has mem size
  759.         jnz  notega                      ; cl has switch settings
  760.         jmp  IsEga
  761.  
  762. notega:                                  ; see if MDA or CGA or HGC    
  763.     mov  ax,40h                 ; seg address of BIOS data area
  764.     mov  es,ax                       ; establish addressibility
  765.     mov  al,byte ptr es:[10h]     ; offset of video status byte
  766.     and  al,00110000b                ; isolate bits 4 & 5
  767.     cmp  al,30h                      ; is it monochrome card?
  768.     je   is_mono                     ; assume color if not mono
  769.     mov  dx,offset msg19A         ; CGA is active adapter
  770.         call dostty
  771.         jmp     chk_ndp
  772.  
  773. is_mono:
  774.     mov  dx,offset msg20         ; MDA is active adapter
  775.         call dostty
  776.         jmp     chk_ndp
  777. IsEga:
  778.         call ega_copy                    ; bl and cl get clobbered
  779.     mov  al,byte ptr es:[87h]     ; offset of EGA BIOS data byte INFO
  780.     shl  al,1
  781.     shl  al,1
  782.     shl  al,1
  783.     shl  al,1
  784.     test al,0h                   ; look for EGA with color
  785.     jnz  nocolor             ; if not, see if mono attached
  786.     mov  dx,offset msg9         ; EGA is active adapter
  787.         call dostty
  788.     mov  al,byte ptr es:[88h]     ; offset of EGA BIOS data byte INFO_3
  789.     shl  al,1
  790.     shl  al,1
  791.     shl  al,1
  792.     shl  al,1
  793.     test al,09h                   ; EGA with ECD in hi res mode
  794.     jnz  nothires             ; set flag if it is, branch if not
  795.     mov  dx,offset msg18         ; 
  796.         call dostty
  797.         jmp  chkmem
  798. nothires:    
  799.     test al,01h                   ; EGA with ECD, EGA in CGA mode
  800.     jnz  noecd             ; set flag if it is, branch if not
  801.     mov  dx,offset msg18A        ; ECD is in CGD emulation mode
  802.         call dostty
  803.         jmp  chkmem
  804. noecd:
  805.     test al,0Eh                   ; EGA with Normal Color Display
  806.     jnz  nocolor             ; set flag if it is, branch if not
  807.     mov  dx,offset msg19         ; 
  808.         call dostty
  809.         jmp  chkmem
  810.  
  811. nocolor:
  812.     test al,0Dh                   ; look for EGA with monochrome display
  813.     jnz  mono2             ; set flag if it is, branch if not
  814.     mov  dx,offset msg20         ; 
  815.         call dostty
  816.         jmp  chkmem
  817. mono2:
  818.     test al,05h                   ; look for EGA with monochrome display
  819.     jnz  badswitch             ; set flag if it is, branch if not
  820.     mov  dx,offset msg20         ; 
  821.         call dostty
  822.         jmp  chkmem
  823. badswitch:                               ; switches must be set incorrectly
  824.     mov  dx,offset msg25         ; 
  825.         call dostty
  826.  
  827. ;
  828. ;***********************************************************************
  829. ;* Test for amount of graphics memory on EGA
  830. ;***********************************************************************
  831. ;
  832. chkmem:
  833.         mov  ax,40h
  834.         mov  es,ax
  835.     mov  al,byte ptr es:[87h]     ; offset of EGA BIOS data byte INFO
  836.     and  al,60h                      ; get rid of unwanted bits
  837.     cmp  al,60h                      ; is 256kb onboard?
  838.     jne  not256                      ; no - check for 192kb
  839.     mov  dx,offset msg17         ; 
  840.         call dostty
  841.         jmp  chk_ndp
  842.  
  843. not256:
  844.     cmp  al,40h                      ; is 192kb onboard? (is IBM EGA)
  845.     jne  not192                      ; no - check for 128kb
  846.     mov  dx,offset msg16         ; 
  847.         call dostty
  848.         jmp  chk_ndp
  849.  
  850. not192:
  851.     cmp  al,20h                      ; is 128kb onboard? (is IBM EGA)
  852.     jne  not128                      ; no - check for 64kb
  853.     mov  dx,offset msg15         ; 
  854.         call dostty
  855.         jmp  chk_ndp
  856.  
  857. not128:                                  ; *must* be 64kb memory (is IBM EGA)
  858.     mov  dx,offset msg14         ; 
  859.         call dostty
  860.         jmp  chk_ndp
  861.  
  862. ;
  863. ;***********************************************************************
  864. ;* Test for presence of 80x87.                                         * 
  865. ;***********************************************************************
  866. ;
  867. chk_ndp:
  868.     fninit                  ; finit - see if 8087 installed
  869.     sub  ax,ax              ; fn means no wait in case no ndp
  870.     mov  word ptr control,ax    ; move two zeros to cntrl reg save area
  871.     fnstcw control                 ; get 8087 control word - no wait
  872.     mov  ax,word ptr control    ; put control word in ax
  873.     and  ax,037Fh                ; default initialization state
  874.     cmp  ax,037Fh                ; equal to 8087 here?
  875.     jne  no_ndp            ; no - go around
  876.     cmp  ps2_flag,30h               ; is it a PS/2 model 50 or above?
  877.         ja   is_80287                   ; if so it's an 80287
  878.     test byte ptr config_flag,01h   ; is this an 80286 class machine ?
  879.         jz   is_8087                    ; if not, NDP is 8087
  880. is_80287:
  881.     mov  dx,offset msg28            ; else it's an 80287
  882.     call dostty
  883.         jmp  getvers
  884. is_8087:
  885.     mov  dx,offset msg27
  886.     call dostty
  887.         jmp  getvers
  888. no_ndp:    
  889.     mov  dx,offset msg29
  890.     call dostty
  891. ;
  892. ;***********************************************************************
  893. ;* Display DOS Version
  894. ;***********************************************************************
  895. ;
  896. getvers:
  897.     mov  dx,offset msg33
  898.     call dostty
  899.         mov  ax,dos_vers
  900.     cmp  ax,0200h                 ; 2.00 or greater?
  901.     ja   isver3
  902.     mov  dx,offset msg38             ; it's 2.00
  903.     call dostty
  904.     jmp  endvers
  905.  
  906. isver3:
  907.     cmp  ax,0300h                 ; 3.00 or greater?
  908.         jae  which3
  909.     mov  dx,offset msg39             ; no, must be 2.10
  910.     call dostty
  911.     jmp  endvers
  912.  
  913. which3:
  914.     cmp  al,0Ah                 ; 3.10 ?
  915.     jne  mustbe32
  916.     mov  dx,offset msg36
  917.     call dostty
  918.     jmp  endvers
  919. mustbe32:
  920.     cmp  al,14h                 ; 3.20 ?
  921.     jne  mustbe33
  922.     mov  dx,offset msg37             ; 3.20
  923.     call dostty
  924.     jmp  endvers
  925. mustbe33:
  926.     cmp  al,1Eh                 ; 3.30 ?
  927.     jne  unk_dos
  928.     mov  dx,offset msg37A            ; 3.30
  929.     call dostty
  930.     jmp  endvers
  931. unk_dos:
  932.     mov  dx,offset msg40             ; unknown version number
  933.     call dostty
  934.     jmp  quit
  935. endvers:
  936. ;
  937. ;***********************************************************************
  938. ;* Display the active switch character
  939. ;***********************************************************************
  940.         cmp  switch_err,0h               ; was there a switchar error?
  941.         je   fcn_37_ok
  942.     mov  dx,offset msg33B
  943.     call dostty
  944. fcn_37_ok:
  945.     mov  dx,offset msg33A
  946.     call dostty
  947.         mov  al,switchar                 ; display the *current* switchar
  948.         call stdout
  949. ;
  950. ;***********************************************************************
  951. ;* Display the active Lpt: ports
  952. ;***********************************************************************
  953. ;
  954. chklpt:
  955.         mov  ax,40h                      ; ROM BIOS data area segment address
  956.         mov  es,ax
  957.         mov  ax,word ptr es:[8h]         ; offset of lpt I/O addresses
  958.         cmp  ax,0h
  959.         je   no_lpt1
  960.         inc  portcnt
  961.     mov  dx,offset newline         
  962.         call dostty
  963.     mov  dx,offset indent          
  964.         call dostty
  965.     mov  dx,offset msg44             ; lpt1:
  966.     call dostty
  967.         call disp_hex
  968.         mov  al,'h'
  969.         call stdout
  970. no_lpt1:
  971.         mov  ax,word ptr es:[0Ah]
  972.         cmp  ax,0h
  973.         je   no_lpt2
  974.         inc  portcnt
  975.     mov  dx,offset newline         
  976.         call dostty
  977.     mov  dx,offset indent          
  978.         call dostty
  979.     mov  dx,offset msg45             ; lpt2:
  980.     call dostty
  981.         call disp_hex
  982.         mov  al,'h'
  983.         call stdout
  984. no_lpt2:
  985.         mov  ax,word ptr es:[0Ch]
  986.         cmp  ax,0h
  987.         je   no_lpt3
  988.         inc  portcnt
  989.     mov  dx,offset newline         
  990.         call dostty
  991.     mov  dx,offset indent          
  992.         call dostty
  993.     mov  dx,offset msg46             ; lpt3:
  994.     call dostty
  995.         call disp_hex
  996.         mov  al,'h'
  997.         call stdout
  998. no_lpt3:
  999.         cmp  portcnt,0h
  1000.         je   no_prns
  1001.         jmp  chkcom
  1002. no_prns:
  1003.     mov  dx,offset newline         
  1004.         call dostty
  1005.     mov  dx,offset indent          
  1006.         call dostty
  1007.     mov  dx,offset msg49             ; no lpt ports found
  1008.     call dostty
  1009. ;
  1010. ;***********************************************************************
  1011. ;* Display the active Com: ports
  1012. ;***********************************************************************
  1013. ;
  1014.  
  1015. chkcom:
  1016.         and  portcnt,0h
  1017.         mov  ax,word ptr es:[0h]         ; offset of com I/O addresses
  1018.         cmp  ax,0h
  1019.         je   no_com1
  1020.         inc  portcnt
  1021.     mov  dx,offset newline         
  1022.         call dostty
  1023.     mov  dx,offset indent          
  1024.         call dostty
  1025.     mov  dx,offset msg47             ; com1:
  1026.     call dostty
  1027.         call disp_hex
  1028.         mov  al,'h'
  1029.         call stdout
  1030. no_com1:
  1031.         mov  ax,word ptr es:[02h]
  1032.         cmp  ax,0h
  1033.         je   no_com2
  1034.         inc  portcnt
  1035.     mov  dx,offset newline         
  1036.         call dostty
  1037.     mov  dx,offset indent          
  1038.         call dostty
  1039.     mov  dx,offset msg48             ; com2:
  1040.     call dostty
  1041.         call disp_hex
  1042.         mov  al,'h'
  1043.         call stdout
  1044. no_com2:
  1045.         mov  ax,word ptr es:[04h]
  1046.         cmp  ax,0h
  1047.         je   no_com3
  1048.         inc  portcnt
  1049.     mov  dx,offset newline         
  1050.         call dostty
  1051.     mov  dx,offset indent          
  1052.         call dostty
  1053.     mov  dx,offset msg48A            ; com3: 
  1054.     call dostty
  1055.         call disp_hex
  1056.         mov  al,'h'
  1057.         call stdout
  1058. no_com3:
  1059.         mov  ax,word ptr es:[06h]
  1060.         cmp  ax,0h
  1061.         je   no_com4
  1062.         inc  portcnt
  1063.     mov  dx,offset newline         
  1064.         call dostty
  1065.     mov  dx,offset indent          
  1066.         call dostty
  1067.     mov  dx,offset msg48B            ; com4: 
  1068.     call dostty
  1069.         call disp_hex
  1070.         mov  al,'h'
  1071.         call stdout
  1072. no_com4:
  1073.         cmp  portcnt,0h
  1074.         je   no_coms
  1075.         jmp  next_chk
  1076. no_coms:
  1077.     mov  dx,offset newline         
  1078.         call dostty
  1079.     mov  dx,offset indent          
  1080.         call dostty
  1081.     mov  dx,offset msg50             ; no com ports found
  1082.     call dostty
  1083. next_chk:
  1084.         dec  optcnt
  1085.     call pause
  1086.  
  1087. ;***********************************************************************
  1088. ;* Display DOS Invar Table Contents.                                   *
  1089. ;***********************************************************************
  1090. invar_chk:
  1091.         cmp  inv_flag,0FFh               ; switch set for invar list?
  1092.         je   disp_invar                  ; yes
  1093.         jmp  chk_dev_drv                 ; no - bypass it.
  1094. disp_invar:                              ; list "Invars" table contents
  1095.     mov  dx,offset newline         
  1096.         call dostty
  1097.     mov  dx,offset scr1
  1098.     call dostty
  1099.     mov  dx,offset newline         
  1100.         call dostty
  1101.     mov  dx,offset space1
  1102.         call dostty
  1103.         mov  ah,52h                      ; undocumented function DOS 2.x or...
  1104.         int  21h                         ; ...greater. Returns pointer to a...
  1105.         push es                          ; ... DOS internal structure in es:bx
  1106.         push bx                          ; save for later
  1107.         push bx                          ;
  1108.         pop  sav_off                     ;
  1109.         mov  ax,es                       ; get Invars seg address for display
  1110.         call disp_hex                    ; display it.
  1111.         call split                       ; print the colon.
  1112.         mov  bx,sav_off                  ; restore offset
  1113.         mov  ax,bx                       ; get Invars off address for display
  1114.         call disp_hex
  1115.     mov  dx,offset space4
  1116.         call dostty
  1117.         mov  bx,sav_off                  ; restore offset
  1118.         mov  ax,es:[bx+2]                ; get DPB segment address for display
  1119.         mov  dpb_seg,ax
  1120.         call disp_hex
  1121.         call split
  1122.         mov  bx,sav_off                  ; restore offset
  1123.         mov  ax,es:[bx]                  ; get DPB offset address for display
  1124.         mov  dpb_off,ax
  1125.         call disp_hex
  1126.     mov  dx,offset space4
  1127.         call dostty
  1128.         mov  bx,sav_off                  ; restore offset
  1129.         mov  ax,es:[bx+6]                ; get cache buffer seg addr 
  1130.         call disp_hex
  1131.         call split
  1132.         mov  bx,sav_off                  ; restore offset
  1133.         mov  ax,es:[bx+4]                ; get cache buffer offset addr 
  1134.         call disp_hex
  1135.     mov  dx,offset space6
  1136.         call dostty
  1137.         mov  bx,sav_off                  ; restore offset
  1138.         mov  ax,es:[bx+10h]              ; get cache buffer size for display
  1139.         add  ax,10h                      ; add in size of overhead bytes (16)
  1140.         call disp_hex
  1141.     mov  dx,offset space8
  1142.         call dostty
  1143.         mov  bx,sav_off                  ; restore offset
  1144.         mov  ax,es:[bx+18h]              ; get drive/directory table seg addr 
  1145.         call disp_hex
  1146.         call split
  1147.         mov  bx,sav_off                  ; restore offset
  1148.         mov  ax,es:[bx+16h]              ; get drive/directory table off addr 
  1149.         call disp_hex
  1150.     mov  dx,offset space5
  1151.         call dostty
  1152.         mov  ah,34h                      ; svc 34h = get DOS "Busy" flag addr
  1153.         int  21h
  1154.         push bx
  1155.         pop  sav_off
  1156.         mov  ax,es                       ; get DOS busy seg address for display
  1157.         call disp_hex
  1158.         call split
  1159.         mov  bx,sav_off                  ; restore offset
  1160.         mov  ax,bx                       ; get DOS busy off address for display
  1161.         call disp_hex
  1162. ;
  1163. ;***********************************************************************
  1164. ;* Display Disk Paramter Blocks.
  1165. ;***********************************************************************
  1166. dpb:
  1167.     mov  dx,offset newline         
  1168.         call dostty
  1169.     mov  dx,offset scr1A
  1170.     call dostty
  1171.     mov  ax,dpb_seg
  1172.     mov  es,ax
  1173.     mov  bx,dpb_off
  1174. dpb_loop:
  1175.     mov  dx,offset newline         
  1176.         call dostty
  1177.         mov  al,byte ptr es:[bx]         ; get drive id
  1178.         add  al,41h                      ; convert to ascii letter
  1179.         call stdout
  1180.         call split
  1181.     mov  dx,offset space2
  1182.         call dostty
  1183.         mov  al,byte ptr es:[bx+01h]     ; get unit number (watch VDISKs)
  1184.                                          ; media descriptor FEh indicates vdisk?
  1185.         add  al,31h                      ; convert to ascii numeral
  1186.         call stdout
  1187.     mov  dx,offset space2
  1188.         call dostty
  1189.         mov  ax,word ptr es:[bx+02h]     ; bytes per sector
  1190.         mov  cx,word ptr es:[bx+05h]     ; num of bits to shift BPS to get BPC
  1191.         shl  ax,cl                       ; multiply it
  1192.         call disp_hex
  1193.     mov  dx,offset space2         ; 
  1194.         call dostty
  1195.         mov  al,byte ptr es:[bx+04h]     ; get Sectors Per Cluster minus 1
  1196.         cmp  al,0FEh                     ; this value indicates that ...
  1197.         je   not_read                    ; ... the drive was never accessed
  1198.         jmp  was_read
  1199. not_read:
  1200.     mov  dx,offset notread
  1201.         call dostty
  1202.     mov  dx,offset space2
  1203.         call dostty
  1204.         jmp  res_sect
  1205. was_read:
  1206.         inc  al                          ; make SPC-1 SPC
  1207.         add  al,30h                      ; make ascii char
  1208.         call stdout
  1209.     mov  dx,offset space3
  1210.         call dostty
  1211. res_sect:
  1212.         mov  ax,word ptr es:[bx+06h]     ; Reserved Sectors
  1213.         call disp_hex
  1214.     mov  dx,offset space2
  1215.         call dostty
  1216.         mov  al,byte ptr es:[bx+08h]     ; get Copies of FAT
  1217.         add  al,30h                      ; make ascii char
  1218.         call stdout
  1219.     mov  dx,offset space2
  1220.         call dostty
  1221.         mov  ax,word ptr es:[bx+09h]     ; Maximum Directory Entries
  1222.         call disp_hex
  1223.     mov  dx,offset space2
  1224.         call dostty
  1225.         mov  ax,word ptr es:[bx+0Bh]     ; First Usable Sector
  1226.         call disp_hex
  1227.     mov  dx,offset space2
  1228.         call dostty
  1229.         mov  ax,word ptr es:[bx+0Dh]     ; Total Cluster Count plus 1
  1230.         dec  ax                          ; make it TCC
  1231.         call disp_hex
  1232.     mov  dx,offset space3
  1233.         call dostty
  1234.         mov  al,byte ptr es:[bx+0Fh]     ; get Sectors in FAT
  1235.         mov  sav_code,al                 ; display low order byte
  1236.     mov  cx,1                     ; count of bytes to display
  1237.         push bx
  1238.     lea  bx,[sav_code]
  1239.         call show_bytes
  1240.         pop  bx
  1241.     mov  dx,offset space2
  1242.         call dostty
  1243.         mov  ax,word ptr es:[bx+10h]     ; get First Directory Sector
  1244.         call disp_hex
  1245.     mov  dx,offset space2
  1246.         call dostty
  1247.         mov  ax,word ptr es:[bx+14h]     ; get dev drv seg addr 
  1248.         call disp_hex
  1249.         call split
  1250.         mov  ax,word ptr es:[bx+12h]     ; get dev drv off addr 
  1251.         call disp_hex
  1252.     mov  dx,offset space2
  1253.         call dostty
  1254.         mov  ax,word ptr es:[bx+16h]     ; get Media Descriptor
  1255.         cmp  al,00h                      ; if zero, drive was never accessed
  1256.         jne  good_md
  1257.     mov  dx,offset notread
  1258.         call dostty
  1259.     mov  dx,offset space2
  1260.         call dostty
  1261.         jmp  next_link
  1262. good_md:
  1263.         mov  sav_code,al                 ; display low order byte
  1264.     mov  cx,1                     ; count of bytes to display
  1265.         push bx
  1266.     lea  bx,[sav_code]
  1267.         call show_bytes
  1268.         pop  bx
  1269.     mov  dx,offset space2
  1270.         call dostty
  1271. next_link:
  1272.         mov  dx,word ptr es:[bx+18h]     ; get off of next dpb
  1273.         cmp  dx,0FFFFh                   ; last dpb in chain?
  1274.         jne  next_dpb
  1275.         jmp  end_dpb
  1276. next_dpb:
  1277.         mov  ax,word ptr es:[bx+1Ah]     ; get next DPB seg addr 
  1278.         call disp_hex
  1279.         call split
  1280.         mov  ax,word ptr es:[bx+18h]     ; get next DPB off addr 
  1281.         call disp_hex
  1282.         mov  ax,word ptr es:[bx+1Ah]     ; get seg of next dpb
  1283.         mov  dx,word ptr es:[bx+18h]     ; get off of next dpb
  1284.         mov  es,ax                       ; establish addressibility
  1285.         mov  bx,dx
  1286.         jmp  dpb_loop
  1287. end_dpb:
  1288.     mov  dx,offset lastdpb
  1289.         call dostty
  1290.     mov  dx,offset newline
  1291.         call dostty
  1292.         dec  optcnt
  1293.         call pause
  1294.         pop  bx
  1295.         pop  es
  1296. ;
  1297. ;***********************************************************************
  1298. ;* Display Device Driver Info.
  1299. ;***********************************************************************
  1300. chk_dev_drv:
  1301.         cmp  drv_flag,0FFh               ; switch set for device driver list?
  1302.         je   nul_dev                     ; yes
  1303.         jmp  chk_tsr                     ; no - bypass driver list
  1304.  
  1305. nul_dev:                                 ; list device driver section
  1306.         mov  ah,52h                      ; undocumented function DOS 2.x or...
  1307.         int  21h                         ; ...greater. Returns pointer to a...
  1308.         push es                          ; ... DOS internal structure in es:bx
  1309.         push bx                          ; save for later
  1310.     mov  dx,offset newline         
  1311.         call dostty
  1312.     mov  dx,offset scr2              
  1313.     call dostty
  1314.     pop  bx
  1315.     pop  es
  1316.         cmp  dos_vers+1,03h              ; Version dependent...
  1317.         je   add_34                      ;
  1318.         add  bx,17h                      ; add 23 byte offset if DOS 2.x
  1319.         jmp  is_two
  1320. add_34:
  1321.         add  bx,22h                      ; add 34 byte offset if DOS 3.x
  1322. is_two:
  1323.         mov  devh_seg,es                 ; segment of device header chain in es
  1324.         mov  devh_off,bx                 ; offset of NUL device now in bx
  1325.         mov  ax,es:[bx+2]                ; get seg of next driver in chain
  1326.         mov  next_seg,ax                 ; save it
  1327.         mov  ax,es:[bx]                  ; get offset of next driver in chain       
  1328.         mov  next_off,ax                 ; save it
  1329.  
  1330. drv_loop:
  1331.         cmp  ax,0FFFFh                   ; end of chain?
  1332.         jne  more_drv
  1333.         jmp  end_drv
  1334. more_drv:
  1335.         mov  ax,es:[bx+2]                ; get seg of next driver in chain
  1336.         mov  next_seg,ax                 ; save it
  1337.         mov  ax,es:[bx]                  ; get off of next driver in chain       
  1338.         mov  next_off,ax                 ; save it
  1339.     mov  dx,offset newline         
  1340.         call dostty
  1341.         mov  sav_off,bx                  ; save offset
  1342.         mov  ax,es:[bx+04h]              ; attribute word
  1343.         mov  type_drv,ax                 ; put it where I can get it
  1344.         test ax,8000h                    ; what kind of device: blk or char?
  1345.         jz   is_block
  1346.         mov  dx,offset char_dev          ; is character device
  1347.         call dostty                      ; display the word "Char"
  1348.         jmp  is_char
  1349. is_block:
  1350.         mov  dx,offset blk_dev           ; is block device
  1351.         call dostty                      ; display the word "Block"
  1352.         call blk_name                    ; format the block device name
  1353.         jmp  clean_up_name
  1354. is_char:
  1355.         mov  ax,word ptr es:[bx+0Ah]     ; move name to my buffer
  1356.         mov  word ptr sav_name+0,ax
  1357.         mov  ax,word ptr es:[bx+0Ch]
  1358.         mov  word ptr sav_name+2,ax
  1359.         mov  ax,word ptr es:[bx+0Eh]
  1360.         mov  word ptr sav_name+4,ax
  1361.         mov  ax,word ptr es:[bx+10h]
  1362.         mov  word ptr sav_name+6,ax
  1363.         mov  ax,2020h                    ; pad name to 12 chars
  1364.         mov  word ptr sav_name+8,ax
  1365.         mov  word ptr sav_name+10,ax
  1366.         mov  word ptr sav_name+12,ax
  1367.         mov  byte ptr sav_name+13,0FFh   ; the field termination character
  1368. clean_up_name:
  1369.         push bx
  1370.         mov  bx, offset sav_name
  1371. scan2:
  1372.         cmp  byte ptr[bx],0FFh           ; are we done? 
  1373.         je   end_scan2                   ; go display it
  1374.         cmp  byte ptr[bx],20h            ; less than a space?
  1375.         jb   hide_it2
  1376.         cmp  byte ptr[bx],'z'            ; greater than lower case z?
  1377.         jna  bump_bx2                    ; if not it's printable
  1378.         
  1379. hide_it2:
  1380.         mov  byte ptr[bx],20h            ; make nonsense characters a space
  1381. bump_bx2:
  1382.         inc  bx                          ; increment the address
  1383.         jmp  scan2                       ; go do it again
  1384. end_scan2:
  1385.         pop  bx
  1386.         mov  dx,offset sav_name          ; print dev name even if block dev
  1387.         call disp_dev_drv
  1388.         mov  dx,offset space2
  1389.         call dostty
  1390.         mov  ax,es                       ; get this driver's seg addr
  1391.         call disp_hex
  1392.         call split
  1393.  
  1394.         mov  bx,sav_off                  ; restore offset
  1395.         mov  ax,bx                       ; get this driver's off addr
  1396.         call disp_hex
  1397.     mov  dx,offset space7         ; 
  1398.         call dostty
  1399.  
  1400.                                          ; strategy offset
  1401.         mov  bx,sav_off                  ; restore offset
  1402.         mov  ax,es:[bx+06h]              ; get strategy offset
  1403.         call disp_hex
  1404.     mov  dx,offset space3         ; 
  1405.         call dostty
  1406.  
  1407.                                          ; interrupt offset
  1408.         mov  bx,sav_off                  ; restore offset
  1409.         mov  ax,word ptr es:[bx+08h]     ; get interrupt offset
  1410.         call disp_hex
  1411.     mov  dx,offset space6         ; 
  1412.         call dostty
  1413.  
  1414.         mov  bx,sav_off                  ; restore offset
  1415.         mov  ax,word ptr es:[bx+04h]     ; get device attribute word
  1416.         call disp_hex
  1417.  
  1418.     mov  dx,offset space5         ; 
  1419.         call dostty
  1420.         mov  ax,type_drv                 ; check DOS version this driver
  1421.         and  ah,08h                      ; ...requires
  1422.         cmp  ah,08h                      ;
  1423.         jne  not_rm                      ; OCREM not supported - a 2.x driver
  1424.         mov  dx,offset msg99             ; OCREM is  supported - a 3.x driver
  1425.         jmp  is_rm
  1426. not_rm:
  1427.         mov  dx,offset msg98
  1428. is_rm:
  1429.         call dostty
  1430.         mov  bx,sav_off                  ; restore offset
  1431.         mov  es,next_seg                 ; get seg of next driver in chain
  1432.         mov  bx,next_off                 ; get off of next driver in chain       
  1433.         mov  ax,bx                       ; set up check for end of chain
  1434.         jmp  drv_loop
  1435. end_drv:
  1436.         dec  optcnt
  1437.     call pause
  1438.  
  1439. ;***********************************************************************
  1440. ;* Display Memory Control Blocks
  1441. ;***********************************************************************
  1442. chk_tsr:                                 ; list MCBs
  1443.         cmp  mem_flag,0FFh               ; switch set for MCB list?
  1444.         je   mem_alloc                   ; yes - go do it
  1445.         jmp  quit                        ; no - quit
  1446.  
  1447. mem_alloc:
  1448.     mov  dx,offset newline         
  1449.         call dostty
  1450.     mov  dx,offset scr3              ; Memory Allocation Screen
  1451.     call dostty
  1452.         mov  ah,52h
  1453.         int  21h
  1454.     mov  ax,es:[bx-2]                ; contains seg address of 1st MCB
  1455.     mov  es,ax                       ; establish addressibility
  1456.     xor  bx,bx                       ; offset will always be zero
  1457.  
  1458. mcb_loop:
  1459.         and  env_flag,0h                 ; set environment found flag "off"
  1460.         and  psp_flag,0h                 ; set PSP found flag "off"
  1461.         and  sys_flag,0h                 ; set system block found flag "off"
  1462.         and  tsr_flag,0h                 ; set TSR flag "off"
  1463.         and  mt_flag,0h                  ; set empty block found flag "off"
  1464.  
  1465.         cmp  byte ptr es:[bx],5Ah        ; hex 5A is last MCB
  1466.         jne  mcb_2
  1467.         jmp  last_mcb                    ; process last one differently
  1468. mcb_2:
  1469.         mov  mcbseg,ax                   ; save for later
  1470.     mov  dx,offset newline         
  1471.         call dostty
  1472.     xor  bx,bx                       ; offset will always be zero
  1473.         call disp_hex
  1474.         mov  dx, offset space2           ; will change as logic is inserted
  1475.         call dostty
  1476.     xor  bx,bx                       
  1477. chk_sys:
  1478.         mov  ax,word ptr es:[bx+1]       ; get seg addr this MCB allocates for
  1479.         cmp  ax,0008h                    ; DOS block always has 0008h here
  1480.         jne  chk_dealloc
  1481.         or   sys_flag,0FFh
  1482.         and  firstsys,0h
  1483. chk_dealloc:                             ; was this block deallocated?
  1484.         push ax
  1485.         mov  ax,word ptr es:[bx+1]       ; get seg addr this MCB allocates for
  1486.         call disp_hex
  1487.         mov  dx, offset space3
  1488.         call dostty
  1489.     xor  bx,bx                       ; offset will always be zero
  1490.         pop  ax
  1491.         cmp  ax,0000h                    ; is block begin zero?
  1492.         jne  paras                       ; if yes, this is empty block
  1493.         or   mt_flag,0FFh                ; set flag (block was deallocated)
  1494. paras:
  1495.         mov  ax,word ptr es:[bx+3]       ; get number of paragraphs allocated
  1496.         call disp_hex
  1497.         mov  dx, offset space2
  1498.         call dostty
  1499.     xor  bx,bx                       ; 
  1500. search_for_env:                          ; does this MCB allocate for an Env?
  1501.         and  env_flag,0h                 ; clear flag
  1502.         cmp  byte ptr es:[bx+10h],43h    ; looking for "C" in "COMSPEC="
  1503.         jne  no_autoexec              ; yes = last MCB controls environment
  1504.         cmp  byte ptr es:[bx+11h],4Fh    ; looking for "O" in "COMSPEC="
  1505.         jne  no_autoexec                 ; if not, maybe no autoexec.bat
  1506.         jmp  env_found
  1507. no_autoexec:                             ; if no autoexec, 1st string is PATH=
  1508.         cmp  byte ptr es:[bx+10h],50h    ; looking for "P" in "PATH="
  1509.         jne  search_for_psp              ; yes = last MCB controls environment
  1510.         cmp  byte ptr es:[bx+11h],41h    ; looking for "A" in "PATH="
  1511.         jne  search_for_psp              ; if not, no environment
  1512. env_found:
  1513.         cmp  firstenv,01h                ; first environment? 
  1514.         je   first_env
  1515.         call get_name                    ; get the name of the process
  1516.         or   tsr_flag,0FFh
  1517. first_env:
  1518.         and  psp_flag,0h                 ; can't be both
  1519.         or   env_flag,0FFh               ; set flag
  1520.         jmp  type_blk
  1521.  
  1522. search_for_psp:                          ; does this MCB allocate for a PSP?
  1523.         and  psp_flag,0h                 ; clear flag
  1524.         cmp  byte ptr es:[bx+10h],0CDh   ; looking for an Int 20h in PSP
  1525.         jne  type_blk
  1526.         cmp  byte ptr es:[bx+11h],20h    ; 
  1527.         jne  type_blk
  1528.         and  env_flag,0h                 ; can't be both
  1529.         or   psp_flag,0FFh               ; set flag for others
  1530.         xor  bx,bx
  1531.         cmp  firstpsp,01h
  1532.         je   type_blk
  1533.         or   tsr_flag,0FFh
  1534. type_blk:
  1535.         cmp  psp_flag,0FFh               ; PSP?
  1536.         jne  type2 
  1537.         mov  dx,offset psptype
  1538.         jmp  end_type
  1539. type2:
  1540.         cmp  env_flag,0FFh               ; environment? 
  1541.         jne  type3 
  1542.         mov  dx,offset envtype
  1543.         jmp  end_type
  1544.  
  1545. type3:
  1546.         cmp  mt_flag,0FFh                ; empty block?
  1547.         jne  type4 
  1548.         mov  dx,offset mttype
  1549.         jmp  end_type
  1550. type4:
  1551.         cmp  sys_flag,0FFh               ; system block?
  1552.         jne  type5 
  1553.         mov  dx,offset systype
  1554.         jmp  end_type
  1555. type5:
  1556.         call data_name                   ; save the filename if any
  1557.         mov  dx,offset datatype          ; it's a data block 
  1558. end_type:
  1559.         call dostty
  1560.         xor  bx,bx
  1561.  
  1562. owner:
  1563.         mov  dx,offset space1
  1564.         call dostty
  1565.         cmp  sys_flag,0FFh               ; is this THE DOS block?
  1566.         jne  owner1  
  1567.         mov  dx,offset sysmsg            ; assume system block 
  1568.         jmp  end_owner
  1569. owner1:                                  ; 
  1570.         cmp  psp_flag,0FFh               ; if it's a psp and...
  1571.         jne  owner2                      ; 
  1572.         cmp  firstpsp,01h                ; ...not the first PSP...
  1573.         jne  is_tsr                      ; 
  1574.         mov  dx,offset cmndmsg           ; it's command.com
  1575.         jmp  end_owner
  1576. owner2:
  1577.         cmp  env_flag,0FFh               ; is it an environment block?
  1578.         jne  owner3
  1579.         cmp  firstenv,01h                ; is it the DOS environment block?
  1580.         jne  is_tsr
  1581.         mov  dx,offset cmndmsg           ; yes, it belongs to COMMAND.COM
  1582.         jmp  end_owner
  1583. owner3:
  1584.         cmp  mt_flag,0FFh                ; is this block empty?
  1585.         jne  owner4
  1586.         mov  dx,offset mtblkmsg          ; assume that this block is empty
  1587.         jmp  end_owner
  1588. owner4:                                  ; must assume this is a data block
  1589.         mov  dx,offset dataname          ; display last env name
  1590.         jmp  end_owner
  1591. is_tsr:                                  ; this block is a TSR   
  1592.         mov  dx,offset filename
  1593. end_owner:
  1594.         call dostty                      ; 
  1595.         xor  bx,bx
  1596.  
  1597. comments:
  1598.         mov  dx,offset space2
  1599.         call dostty
  1600. comment1:
  1601.         cmp  env_flag,0FFh               ; environment? 
  1602.         jne  comment2 
  1603.         cmp  firstenv,01h                ; first environment? 
  1604.         je   comment4
  1605.         mov  dx,offset envmsg            ; process environment
  1606.         jmp  end_comment
  1607. comment2:
  1608.         cmp  sys_flag,0FFh               ; is this a system owned block?
  1609.         jne  comment3
  1610.         mov  dx,offset drvmsg            ; dev drvs, etc.
  1611.         jmp  end_comment
  1612. comment3:
  1613.         cmp  mt_flag,0FFh                ; is this block empty?
  1614.         jne  comment5
  1615.         mov  dx,offset de_allocmsg       ; assume that this block is empty
  1616.         jmp  end_comment
  1617. comment4:
  1618.         mov  dx,offset mastenv           ; this is the DOS master environment
  1619.         and  firstenv,0h                 ; there can be only one
  1620.         jmp  end_comment
  1621. comment5:
  1622.         cmp  psp_flag,0FFh               ; is this a tsr?
  1623.         jne  comment7
  1624.         cmp  firstpsp,01h                ; first PSP?
  1625.         je   comment6
  1626.         mov  dx,offset tsrmsg            ; TSR
  1627.         jmp  end_comment
  1628. comment6:
  1629.         mov  dx,offset resdmsg           ; resident part of command.com
  1630.         and  firstpsp,0h                 ; there can be only one
  1631.         jmp  end_comment
  1632. comment7:
  1633.         mov  dx,offset datamsg           ; must assume process data
  1634.         jmp  end_comment
  1635. end_comment:
  1636.         call dostty
  1637.         xor  bx,bx
  1638. ;***********************************************************************
  1639. ;* Display the command line arguments for this TSR
  1640. ;***********************************************************************
  1641. args:
  1642.         call chk_args
  1643. ;***********************************************************************
  1644. ;* Find and display any interrupt vectors hooked by this TSR.          *
  1645. ;***********************************************************************
  1646. chk_vec:                                 ; print hooked vectors here
  1647.         mov  dx,word ptr es:[bx+3]       ; get number of paragraphs allocated
  1648.         mov  ax,es                       ; get mcb seg
  1649.         inc  ax                          ; account for length of mcb
  1650.         mov  blk_beg,ax                  ; this is where the blk begins
  1651.         add  ax,dx                       ; add the length of the blk
  1652.         mov  blk_end,ax                  ; this is where the blk ends
  1653.         push es
  1654.         mov  ax,0h
  1655.         mov  es,ax
  1656.         and  vectcnt,0h
  1657.         mov  dx,vectcnt
  1658.         mov  cl,4
  1659.         mov  cnt,0h
  1660. vect_loop:
  1661.         shl  dx,1                        ; multiply the interrupt number...
  1662.         shl  dx,1                        ; ...by 4 to get offset of vector...
  1663.         mov  bx,dx                       ; .....in table.
  1664.         mov  ax,word ptr es:[bx+2]       ; get the vector segment
  1665.         mov  dx,word ptr es:[bx]         ; get the vector offset
  1666.         shr  dx,cl                       ; divide by 16 to get paragraphs
  1667.         add  ax,dx                       ; add them to get seg addr of entry
  1668.         cmp  ax,blk_beg                  ; compare the mcb seg and int seg
  1669.         jnb  chk_end                     ; int seg is greater...chk end seg
  1670.         jmp  not_hooked
  1671. chk_end:
  1672.         cmp  ax,blk_end                  ; compare the ending seg and int seg
  1673.         jna  is_hooked                   ; if int seg less, vector is hooked
  1674.         jmp  not_hooked                  ; ...otherwise it's not.
  1675. is_hooked:
  1676.         mov  ax,vectcnt                  ; print the interrupt number
  1677.         mov  sav_addr,ax                 ; put it where display routine wants
  1678.     mov  cx,1                     ; count of bytes to display
  1679.     lea  bx,[sav_addr]
  1680.         call show_bytes                  
  1681.         mov  dx, offset space1
  1682.         call dostty
  1683.         inc  cnt
  1684.         cmp  cnt,05h
  1685.         jbe  not_hooked                  ; see if we have to wrap the line
  1686.         and  cnt,0h
  1687.     mov  dx,offset newline
  1688.         call dostty
  1689.         call chk_screen
  1690.         mov  dx,offset space12
  1691.         call dostty                      ; align the wrap line
  1692.         mov  dx,offset space12
  1693.         call dostty
  1694.         mov  dx,offset space12
  1695.         call dostty
  1696.         mov  dx,offset space12
  1697.         call dostty
  1698.         mov  dx,offset space11
  1699.         call dostty
  1700.  
  1701. not_hooked:
  1702.         mov  cl,4
  1703.         inc  vectcnt                     ; increment interrupt type number
  1704.         cmp  vectcnt,078h                ; not interested in types > 78h
  1705.         ja   done_vect
  1706.         mov  dx,vectcnt
  1707.         jmp  vect_loop
  1708. done_vect:
  1709.         call chk_screen
  1710.         pop  es
  1711. end_mcb_loop:                              
  1712.     xor  bx,bx                       ; offset will always be zero
  1713.         mov  ax,mcbseg                   ; seg addr of MCB
  1714.         mov  dx,word ptr es:[bx+3]       ; get number of paragraphs allocated
  1715.         add  ax,dx                       ; add paragraphs allocated to seg addr
  1716.         inc  ax                          ; +16 to account for the MCB length
  1717.         mov  es,ax                       ; this is the new seg addr
  1718.         jmp  mcb_loop
  1719.  
  1720. ;***********************************************************************
  1721. ;* This is the MCB for snoop.com                                       *
  1722. ;***********************************************************************
  1723. last_mcb:
  1724.         or   psp_flag,0FFh
  1725.     mov  dx,offset newline         
  1726.         call dostty
  1727.         xor  bx,bx
  1728.         call disp_hex
  1729.         mov  dx, offset space2           
  1730.         call dostty
  1731.         xor  bx,bx
  1732.         mov  ax,word ptr es:[bx+1]       ; get seg addr this MCB allocates for
  1733.         call disp_hex
  1734.         mov  dx, offset space3
  1735.         call dostty
  1736.         xor  bx,bx
  1737.         mov  ax,word ptr es:[bx+3]       ; get number of paragraphs allocated
  1738.         call disp_hex
  1739.         mov  dx, offset space2
  1740.         call dostty
  1741.         mov  dx, offset psptype
  1742.         call dostty
  1743.         mov  dx,offset space1
  1744.         call dostty
  1745.         mov  dx,offset filename
  1746.         call dostty
  1747.         mov  dx,offset space2
  1748.         call dostty
  1749.         mov  dx,offset thismsg           ; assume that this block is free
  1750.         call dostty
  1751.         call chk_args
  1752.     mov  dx,offset newline         
  1753.         call dostty
  1754. ;***********************************************************************
  1755. ;* End of Job.                                                         *
  1756. ;***********************************************************************
  1757. quit:
  1758.     mov  ax,4C00h                 ; Return code for normal completion
  1759.     int  21h             ; return to DOS
  1760. main    endp
  1761. ;
  1762. ;
  1763. ;***********************************************************************
  1764. ;
  1765. ;  Called procedures (Near)
  1766. ;
  1767. ;***********************************************************************
  1768. ;
  1769. ;***********************************************************************
  1770. ;* DOS TTY Write
  1771. ;***********************************************************************
  1772. dostty  proc near
  1773.         push ax
  1774.     mov  ah,09h             ; ah=09h: display string at ds:dx
  1775.     int  21h
  1776.         pop  ax
  1777.     ret
  1778. dostty  endp
  1779.  
  1780. ;***********************************************************************
  1781. ;* DOS Display Single Character
  1782. ;***********************************************************************
  1783.  
  1784. dos_char proc near
  1785.         push ax
  1786.         mov  ah,2                        ; ah=02h: display char in dl
  1787.         int  21h
  1788.         pop  ax
  1789.         ret
  1790. dos_char endp
  1791.  
  1792. ;***********************************************************************
  1793. ;* Prints a colon between seg and offset addresses
  1794. ;***********************************************************************
  1795. split    proc near
  1796.     push ax
  1797.     mov  al,colon
  1798.     call show_ascii
  1799.     pop  ax
  1800.     ret
  1801. split    endp
  1802.  
  1803. ;***********************************************************************
  1804. ;* Prints a single space
  1805. ;***********************************************************************
  1806. space    proc near
  1807.     push ax
  1808.     mov  al,blank
  1809.     call show_ascii
  1810.     pop  ax
  1811.     ret
  1812. space    endp
  1813.  
  1814. ;***********************************************************************
  1815. ;* Converts Hex numbers for display.
  1816. ;***********************************************************************
  1817. show_bytes proc    near
  1818.     push ax
  1819.     push bx
  1820.     push cx
  1821. sbs_loop:
  1822.     mov  al,[bx]
  1823.     call show_byte
  1824.     inc  bx
  1825.     loop sbs_loop
  1826.     pop  cx
  1827.     pop  bx
  1828.     pop  ax
  1829.     ret
  1830. show_bytes endp
  1831.  
  1832. ;***********************************************************************
  1833. ;* Convert the hex character.
  1834. ;***********************************************************************
  1835. show_byte proc near
  1836.     pushf
  1837.     push cx
  1838.     push ax
  1839.     mov  cl,4h    ;shift rt 4 bits
  1840.     shr  al,cl    ;to isolate m.s. nybble
  1841.     call test    ;display hex contents
  1842.     pop  ax            ;retrieve al
  1843.     and  al,0fh    ;isolate l.s. nybble
  1844.     call test    ;display hex contents
  1845.     pop  cx
  1846.     popf
  1847.     ret
  1848. show_byte endp
  1849.  
  1850. ;***********************************************************************
  1851. ;* Determines if hex digit is a letter.
  1852. ;***********************************************************************
  1853. test    proc near
  1854.     cmp  al,9h    ;is nybble letter?
  1855.     ja   letter    ;if so convert to letter
  1856.     or   al,30h    ;if not add '30' code
  1857.     jmp  display
  1858. letter:
  1859.     sub  al,9h    ;reduce letter nybble by 9
  1860.     or   al,40h    ;add '40' code
  1861. display:
  1862.     call show_ascii
  1863.     ret    
  1864. test    endp
  1865.  
  1866. ;***********************************************************************
  1867. ;* Displays ASCII characters.
  1868. ;***********************************************************************
  1869. show_ascii    proc     near
  1870.     push ax
  1871.     push dx
  1872.     mov  dl,al
  1873.     mov  ah,02h            ;ah=02: display char in dl         
  1874.     int  21h
  1875.         pop  dx
  1876.     pop  ax
  1877.     ret
  1878. show_ascii endp
  1879. ;
  1880. ;*************************************************************************
  1881. ;* dec16out - Routine to convert internal 16 bit binary to ASCII decimal *
  1882. ;*************************************************************************
  1883. dec16out proc near
  1884. dec16out0:
  1885.     push ds
  1886.     push di
  1887.     push dx
  1888.     push cx
  1889.     push ax
  1890.     mov ax,cs
  1891.     mov ds,ax
  1892.                                          ; a binary number is in dx
  1893.                                          ; put the digits in a temporary buffer
  1894.     mov cx,0
  1895.     mov di, offset cs:tbuff          ; point to buffer
  1896. dec16out1:
  1897.     push cx
  1898.     mov  ax,dx                 ; ax has numerator
  1899.     mov  dx,0        
  1900.     mov  cx,10d                 ; divisor of 10
  1901.     div  cx
  1902.     xchg ax,dx                 ; get quotient
  1903.     add  al,30h
  1904.     mov  [di],al                 ; put in buffer
  1905.     inc  di                     ; point to next byte
  1906.     pop  cx
  1907.     inc  cx                     ; count the digit
  1908.     cmp  dx,0                 ; done?
  1909.     jnz  dec16out1
  1910.                                          ; dump the buffer out
  1911. dec16out2:
  1912.     dec  di                     ; back up through the buffer
  1913.     mov  al,[di]
  1914.     call stdout
  1915.     loop dec16out2
  1916.     pop  ax
  1917.     pop  cx
  1918.     pop  dx
  1919.     pop  di
  1920.     pop  ds
  1921.     ret
  1922. dec16out endp
  1923. ;
  1924. ;***********************************************************************
  1925. ;* Display device driver names so embedded "$" while display.
  1926. ;***********************************************************************
  1927. disp_dev_drv proc near
  1928.         push bx
  1929.         push si                          ; save the count
  1930.         xor  si,si
  1931.         mov  bx,dx
  1932. disp_drv_loop:
  1933.         cmp  byte ptr ds:[bx+si],0FFh    ; the field termination character
  1934.         je   end_drv_loop
  1935.         mov  al,byte ptr ds:[bx+si]      ; set it up for stdout
  1936.         call stdout
  1937.         inc  si
  1938.         cmp  si,0Dh                      ; paranoia: are we done yet?
  1939.         je   end_drv_loop
  1940.         jmp  disp_drv_loop
  1941. end_drv_loop:
  1942.         pop  si
  1943.         pop  bx
  1944.         ret
  1945. disp_dev_drv endp
  1946. ;
  1947. ;***********************************************************************
  1948. ;* Sends a character to the std ouput device.
  1949. ;***********************************************************************
  1950. stdout  proc near
  1951.     push dx
  1952.     mov  dl,al        ;in dl for DOS call
  1953.     mov  ah,2        ;send character to std output
  1954.     int  21h
  1955.     pop  dx
  1956.     ret
  1957. stdout  endp                
  1958. ;***********************************************************************
  1959. ;* Finds EGA Copyright String.
  1960. ;***********************************************************************
  1961. ega_copy proc near
  1962.         cmp  ps2_flag,0h                 ; PS/2 series has onboard VGA
  1963.         je   not_vga                     ; and therefore no EGA copyright
  1964.         jmp  vga_exit
  1965. not_vga:
  1966.     mov  dx,offset newline         
  1967.         call dostty
  1968.     mov  dx,offset indent          
  1969.         call dostty
  1970.     mov  dx,offset egacopy         ; copyright header
  1971.         call dostty
  1972.         push es
  1973.         push ds
  1974.         push ds
  1975.         pop  es                          ; destination string address in es:di
  1976.         mov  ax,0C000h                   ; source string address in ds:si
  1977.         mov  ds,ax                       ; ...location of IBM EGA copyright
  1978.         mov  ax,05h                      ; 
  1979.         mov  cx,11h                      ; count of words in copyright
  1980.         mov  bx,cx                       ;
  1981.         shl  bx,1                        ; multiply by 2 then subtract 1...
  1982.         dec  bx                          ; ... to get offset of...
  1983.         mov  si,ax                       ; terminator character in dest string
  1984.         mov  di,offset es:tbuff
  1985.         rep  movsw
  1986.         pop  ds
  1987.         pop  es
  1988.         mov  byte ptr tbuff+[bx],'$'    ; insert terminator
  1989.         mov  bx, offset tbuff
  1990. scan_copy:
  1991.         cmp  byte ptr[bx],'$'           ; are we done?
  1992.         je   done_copy                  ; go display it
  1993.         cmp  byte ptr[bx],' '           ; less than a space?
  1994.         jb   mask_it                    ;
  1995.         cmp  byte ptr[bx],'~'           ; greater than a tilde
  1996.         jna  inc_bx                     ; if not it's printable
  1997.         
  1998. mask_it:
  1999.         mov  byte ptr[bx],20h           ; make nonsense characters a space
  2000. inc_bx:
  2001.         inc  bx                         ; increment the address
  2002.         jmp  scan_copy                  ; go do it again
  2003. done_copy:
  2004.         mov  dx,offset tbuff            ; 
  2005.         call dostty
  2006.         push es
  2007.         push ds
  2008.         push ds
  2009.         pop  es                          ; destination string address in es:di
  2010.     mov  dx,offset newline         
  2011.         call dostty
  2012.     mov  dx,offset indent          
  2013.         call dostty
  2014.     mov  dx,offset egadate         ; date header
  2015.         call dostty
  2016.         mov  ax,0C000h                   ; source string address in ds:si
  2017.         mov  ds,ax
  2018.         mov  ax,26h                      ; offset of EGA rom release date
  2019.         mov  si,ax
  2020.         mov  di,offset es:tbuff
  2021.         mov  cx,04h                      ; count of words
  2022.         rep  movsw
  2023.         pop  ds
  2024.         pop  es
  2025.         mov  byte ptr tbuff[07h],'$'
  2026.         mov  dx,offset tbuff             ; 
  2027.         call dostty
  2028. vga_exit:
  2029.         ret
  2030. ega_copy endp
  2031. ;***********************************************************************
  2032. ;* Division Routine.
  2033. ;***********************************************************************
  2034. divide  proc near
  2035.         mov  ax,bx
  2036.         xor  dx,dx
  2037.         div  cx
  2038.         mov  bx,dx
  2039.         mov  dl,al
  2040.         cmp  al,0
  2041.         jz   chk_flag
  2042.         or   display_flag,al
  2043. chk_flag:
  2044.         cmp  display_flag,0
  2045.         ja   display_it
  2046.         ret
  2047. display_it:
  2048.         add  dl,30h
  2049.         call dos_char
  2050.         ret
  2051. divide  endp
  2052. ;***********************************************************************
  2053. ; Pause the scrolling display.
  2054. ;***********************************************************************
  2055. pause   proc near
  2056.         cmp  byte ptr pse_flag,0h        ; are we to pause the display?
  2057.         jne  no_pause                    ; if pause is zero we will
  2058.         cmp  byte ptr optcnt,0h          ; last option?
  2059.         jbe  no_pause                    ; if so don't pause
  2060.         push dx
  2061.     mov  dx,offset msg7         ; 
  2062.         call dostty
  2063.     mov  ah,get_key                  ; function number
  2064.     int  16h                         ; ascii code for key pressed in ah
  2065.         pop  dx
  2066. no_pause:
  2067.         ret                              ; yes - return to caller
  2068. pause   endp
  2069.  
  2070. ;***********************************************************************
  2071. ;* Get a block device driver's name into a buffer for display.
  2072. ;***********************************************************************
  2073. blk_name proc near
  2074.         mov  al,byte ptr es:[bx+0Ah]     ; first byte is number of units
  2075.         add  al,30h                      ; make it ascii
  2076.         mov  ah,20h                      ; add a space
  2077.         mov  word ptr sav_name,ax        ; store it
  2078.         mov  ax,es:[bx+12h]              ; remainder of name...
  2079.         mov  word ptr sav_name+2,ax
  2080.         mov  ax,es:[bx+14h]              ; ...if any, follows units...
  2081.         mov  word ptr sav_name+4,ax
  2082.         mov  ax,es:[bx+16h]              ; ...and may include...
  2083.         mov  word ptr sav_name+6,ax
  2084.         mov  ax,es:[bx+18h]              ; ....some garbage characters...
  2085.         mov  word ptr sav_name+8,ax
  2086.         mov  ax,es:[bx+1Ah]              ; ...whic is unavoidable...
  2087.         mov  word ptr sav_name+10,ax
  2088.         mov  ax,es:[bx+1Ch]              ; ...because I want to see the name.
  2089.         mov  word ptr sav_name+12,ax
  2090.         mov  byte ptr sav_name+13,0FFh   ; the field termination character
  2091.         ret
  2092. blk_name endp
  2093. ;
  2094.  
  2095. ;***********************************************************************
  2096. ;* Search for Task Name in Command Line in Environment.
  2097. ;***********************************************************************
  2098. get_name proc near
  2099.         cmp  dos_vers+1,02h              ; name not available in DOS 2.x
  2100.         ja   vers_ok
  2101.         mov  arg_cnt,0h                  ; ignore switches
  2102.         jmp  quick_x                     ; display spaces for owner name
  2103. vers_ok:
  2104.         mov  dx,0000h
  2105.         mov  bx,10h
  2106.         mov  cx,532h                     ; env can't be longer than this
  2107. look_for:
  2108.         dec  cx
  2109.         cmp  cx,0h                       ; have we checked 1,330 chars?
  2110.         jne  not_1330                    ; no, continue the search
  2111.         mov  arg_cnt,0h                  ; yes, ignore switches
  2112.         jmp  quick_x                     ; display spaces for owner name
  2113. not_1330:
  2114.         inc  bx                          ; a byte at a time.....
  2115.         cmp  word ptr es:[bx],dx         ; ...look for back to back ascii nuls
  2116.         jne  look_for
  2117.         add  bx,2                        ; found them...
  2118.         mov  ax,word ptr es:[bx]         ; ... get count of command line args
  2119.         mov  arg_cnt,ax
  2120.         add  bx,3
  2121.         cmp  byte ptr es:[bx],':'         ; ...looking for :\
  2122.         je   not_netware
  2123.         mov  arg_cnt,0h                  ; ignore switches
  2124.         jmp  quick_x                     ; display spaces for owner name
  2125. not_netware:
  2126.         inc  bx                          ; step over ":"
  2127.         cmp  byte ptr es:[bx],5Ch        ; ...looking for "\" path delimiter
  2128.         je   not_novelle
  2129.         cmp  byte ptr es:[bx],2Fh        ; ...looking for "/" path delimiter
  2130.         je   not_novelle                 ; Novelle Netware does not use either
  2131.         mov  arg_cnt,0h                  ; won't find task name so ignore
  2132.         jmp  quick_x                     ; display spaces for owner name
  2133. not_novelle:
  2134.         inc  bx                          ; step over the "\" or "/"
  2135.         mov  di,offset filename
  2136.         mov  si,bx                       ; si is offset of beginning of name
  2137.         xor  cx,cx
  2138. mov_name:
  2139.         cmp  byte ptr es:[si],5Ch        ; looking for embedded '\' in path
  2140.         je   restart_scan
  2141.         cmp  byte ptr es:[si],2Fh        ; looking for embedded '/' in path
  2142.         jne  no_path
  2143. restart_scan:
  2144.         mov  di,offset filename          ; reset dest offset to beginning
  2145.         inc  si                          ; bump si past '\' or '/'
  2146.         xor  cx,cx
  2147.         jmp  mov_name                    ; go back and start again
  2148. no_path:
  2149.         cmp  byte ptr es:[si],2Eh        ; looking for '.' to exclude extension
  2150.         je   end_name
  2151.         cmp  cx,8h                       ; filename is 8 chars long max
  2152.         je   fini
  2153.         mov  al,byte ptr es:[si]
  2154.         mov  byte ptr ds:[di],al
  2155.         inc  si
  2156.         inc  di
  2157.         inc  cx
  2158.         jmp  mov_name
  2159. end_name:
  2160.         cmp  cx,8h                       ; filename is 8 chars long
  2161.         jnb  fini
  2162.         mov  byte ptr ds:[di],20h
  2163.         inc  di
  2164.         inc  cx
  2165.         jmp  end_name
  2166. fini:
  2167.         mov  byte ptr ds:[di],'$'
  2168. quick_x:
  2169.     xor  bx,bx                       ; offset will always be zero
  2170.         ret
  2171. get_name endp
  2172. ;***********************************************************************
  2173. ;* Save the filename for data blocks
  2174. ;***********************************************************************
  2175. ;
  2176. data_name proc near
  2177.         cmp  byte ptr filename,20h       ; will be a space first time around
  2178.         jne  not_first
  2179.     call get_owner             ; find the owning task name
  2180. not_first:
  2181.         cmp  data_flag,0FFh              ; if set, name is already in place
  2182.         je   data_exit                   ; exit if it is
  2183.         push es                          ; save MCB seg addr
  2184.         push ds                          ; establish addressibility
  2185.         pop  es                          ; destination string address in es:di
  2186.         mov  ax,offset filename          ; offset of filename 
  2187.         mov  si,ax                       ; set up source index
  2188.         mov  di,offset es:dataname       ; set up destination index
  2189.         mov  cx,04h                      ; count of words (8 bytes)
  2190.         rep  movsw                       ; do the move
  2191.         mov  byte ptr dataname[08h],'$'  ; string terminator for DOS
  2192.         or   data_flag,0FFh              ; set it for next time
  2193.         pop  es                          ; restore MCB seg addr
  2194. data_exit:
  2195.         ret
  2196. data_name endp
  2197. ;
  2198. ;***********************************************************************
  2199. ;* Get name of task that owns this data block.
  2200. ;***********************************************************************
  2201. get_owner proc near
  2202.     push es
  2203.     push bx
  2204.     xor  bx,bx
  2205.     mov  ax,word ptr es:[bx+1]      ; get seg addr of blk this MCB controls
  2206.     mov  es,ax                       ; es now points to PSP of owner
  2207.     mov  ax,word ptr es:[bx+2Ch]     ; get seg addr of environment
  2208.     mov  es,ax                       ; es now points to Env of owner
  2209.     call get_name                    ; call the normal get name routine    
  2210.     pop  bx
  2211.     pop  es
  2212.     ret
  2213. get_owner endp
  2214. ;
  2215. ;***********************************************************************
  2216. ;* Display Hex Numbers.
  2217. ;***********************************************************************
  2218. disp_hex proc near
  2219.         push bx
  2220.         xchg ah,al                       ; get it turned around
  2221.         mov  sav_addr,ax                 ; 
  2222.     mov  cx,2                     ; count of bytes to display
  2223.     lea  bx,[sav_addr]
  2224.         call show_bytes
  2225.         pop  bx
  2226.         ret
  2227. disp_hex endp
  2228. ;
  2229. ;***********************************************************************
  2230. ;*  Check for command line switches in the TSR's PSP.                  *
  2231. ;***********************************************************************
  2232. chk_args proc near
  2233.         push bx
  2234.         cmp  psp_flag,0FFh               ; is this a PSP?
  2235.         jne  no_args
  2236.         cmp  arg_cnt,0h                  ; any command line switches?
  2237.         je   no_args
  2238.         mov  bx,90h                      ; offset of count (including MCB)
  2239.         mov  ax,es:[bx]                  ; PSP arg cnt
  2240.         cmp  ax,0h                       ; any args?
  2241.         je   end_args
  2242.         inc  bx                          ; point to tail
  2243. arg_loop:
  2244.         cmp  byte ptr es:[bx],0Dh        ; CR ends tail
  2245.         je   end_args
  2246.         mov  al,es:[bx]
  2247.         call stdout
  2248.         inc  bx                          ; bump offset
  2249.         cmp  bx,9Bh                      ; only room for 9 characters
  2250.         jb   arg_loop
  2251. end_args:
  2252.         sub  bx,91h                      ; get number of spaces to print
  2253.         cmp  bx,0h
  2254.         jbe  no_args                     ; if negative, no args        
  2255.         mov  cx,0Ch
  2256.         sub  cx,bx
  2257. fill_loop:
  2258.         mov  al,20h
  2259.         call stdout
  2260.         loop fill_loop
  2261.         jmp  exit_args
  2262. no_args:
  2263.         mov  dx,offset space12           ; change # of spaces for args print
  2264.         call dostty                      ; 
  2265. exit_args:
  2266.         pop  bx
  2267.         ret
  2268. chk_args endp
  2269. ;***********************************************************************
  2270. ;* See if 80286 or 80386 CPU using Intel approved method
  2271. ;***********************************************************************
  2272. chk_cpu proc near
  2273.         push ax
  2274.         mov  cpu_flag,0h                 ; clear it
  2275.         pushf                            ; save original flags
  2276.         pushf                            ; make extra copy of flags register..
  2277.         pop  ax                          ; bits 12-14 can be set on a 386 only
  2278.         or   ax,0111000000000000b        ; turn on bits 12-14
  2279.         push ax                          ; 
  2280.         popf                             ; pop this value back into flags reg
  2281.         pushf                            ; 
  2282.         pop  ax                          ; look at results
  2283.         and  ax,0111000000000000b        ; see if bits 12-14 are set
  2284.         jnz  is_32_bit                   ; if they're set, it's a 386 cpu        
  2285. is_16_bit:
  2286.         popf                             ; restore flags
  2287.     or   byte ptr cs:cpu_flag,02h    ; indicate 286 cpu
  2288.         jmp  cpu_exit
  2289. is_32_bit:
  2290.         popf                             ; restore flags
  2291.     or   byte ptr cs:cpu_flag,03h    ; indicate 386 cpu
  2292.         jmp  cpu_exit
  2293. cpu_exit:
  2294.         pop  ax
  2295.         ret
  2296. chk_cpu endp
  2297. ;
  2298. ;***********************************************************************
  2299. ;* Check to see if this is an IBM Personal System/2 Machine    *
  2300. ;***********************************************************************
  2301. ; Model Id Byte values and meanings:
  2302. ;
  2303. ; IBM Personal System/2 Model 30
  2304. ; at address F000:FFFE FA 
  2305. ;
  2306. ; IBM Personal System/2 Model 50
  2307. ; at address E000:7AF9 FC 04 <====Rom Revision Level 4.
  2308. ;
  2309. ; IBM Personal System/2 Model 60
  2310. ; at address E000:7B03 FC 05 <====Rom Revision Level 5.
  2311. ;
  2312. ; IBM Personal System/2 Model 80
  2313. ; at address E000:xxxx F8 00           F8 is an educated guess
  2314. ;
  2315. chk_ps2 proc near
  2316.         and  ps2_flag,0h
  2317.         cmp  word ptr es:[bx+2],04FCh
  2318.         je   model_50
  2319.         cmp  word ptr es:[bx+2],05FCh
  2320.         je   model_60
  2321.         cmp  byte ptr es:[bx+2],0F8h
  2322.         je   need_386
  2323.         jmp  unkn_model
  2324. need_386:
  2325.         call chk_cpu
  2326.     cmp  byte ptr cs:cpu_flag,03h    ; is it a 386 cpu?
  2327.         je   model_80
  2328.         jmp  unkn_model                  ; it's an 80286, 8088, or 8086 
  2329. model_50:
  2330.     or   ps2_flag,50h
  2331.     mov  dx,offset msg1F
  2332.         call dostty
  2333.         jmp  end_ps2
  2334. model_60:
  2335.     or   ps2_flag,60h
  2336.     mov  dx,offset msg1G
  2337.         call dostty
  2338.         jmp  end_ps2
  2339. model_80:
  2340.     or   ps2_flag,80h
  2341.     mov  dx,offset msg1H
  2342.         call dostty
  2343.         jmp  end_ps2
  2344. unkn_model:                              ; probably a PC Convertible
  2345. end_ps2:
  2346.         ret                    
  2347. chk_ps2 endp
  2348. ;
  2349. ;***********************************************************************
  2350. ;* chk_mod30 - Check if this is a PS/2 Model 30.
  2351. ;***********************************************************************
  2352.  
  2353. chk_mod30 proc near
  2354.     cmp  al,0FAh                  ; PS/2 Model 30?
  2355.         je   model_30
  2356.         jmp  end_30
  2357. model_30:
  2358.     or   ps2_flag,30h
  2359.     mov  dx,offset msg1E
  2360.         call dostty
  2361. end_30:
  2362.         ret
  2363. chk_mod30 endp
  2364.  
  2365. ;
  2366. ;***********************************************************************
  2367. ;* chk_switch - Check command line switches for options requested.     *                           *
  2368. ;***********************************************************************
  2369. chk_switch proc near
  2370.         mov  cl,ds:[0080h]               ; command line arg count in PSP
  2371.         cmp  cl,0h                       ; any args?
  2372.         ja   swt_set
  2373.         jmp  end_swt
  2374. swt_set:
  2375.         mov  bx,80h                      ; offset-1 of command tail in PSP
  2376. swt_char:
  2377.         inc  bx
  2378.         cmp  byte ptr ds:[bx],0Dh       ; CR ends command tail
  2379.         jne  more_swt
  2380.         jmp  end_swt
  2381. more_swt:
  2382.         cmp  byte ptr ds:[bx],'/'
  2383.         je   fnd_swt
  2384.         cmp  byte ptr ds:[bx],'\'
  2385.         je   fnd_swt
  2386.         cmp  byte ptr ds:[bx],' '
  2387.         je   fnd_swt
  2388.         cmp  byte ptr ds:[bx],'-'
  2389.         je   fnd_swt
  2390.         jmp  swt_char
  2391. fnd_swt:
  2392.         inc  bx
  2393.         or   byte ptr ds:[bx],20h
  2394.         cmp  byte ptr ds:[bx],'n'
  2395.         jne  chk_equ
  2396.         or   pse_flag,0FFh
  2397.         and  byte ptr one,0h             ; value to add to the line counter
  2398.         jmp  swt_char
  2399. chk_equ:
  2400.         cmp  byte ptr ds:[bx],'e'
  2401.         jne  chk_inv
  2402.         or   equ_flag,0FFh
  2403.         inc  optcnt
  2404.         jmp  swt_char
  2405. chk_inv:
  2406.         cmp  byte ptr ds:[bx],'i'
  2407.         jne  chk_drv
  2408.         or   inv_flag,0FFh
  2409.         inc  optcnt
  2410.         jmp  swt_char
  2411. chk_drv:
  2412.         cmp  byte ptr ds:[bx],'d'
  2413.         jne  chk_mcb
  2414.         or   drv_flag,0FFh
  2415.         inc  optcnt
  2416.         jmp  swt_char
  2417. chk_mcb:
  2418.         cmp  byte ptr ds:[bx],'m'
  2419.         jne  all_chk
  2420.         or   mem_flag,0FFh
  2421.         inc  optcnt
  2422.         jmp  swt_char
  2423. all_chk:
  2424.         cmp  byte ptr ds:[bx],'a'
  2425.         jne  klone_chk
  2426.         or   equ_flag,0FFh
  2427.         or   inv_flag,0FFh
  2428.         or   drv_flag,0FFh
  2429.         or   mem_flag,0FFh
  2430.         or   argc,0FFh
  2431.         jmp  swt_char
  2432. klone_chk:                               ; option for MS-DOS boxes
  2433.         cmp  byte ptr ds:[bx],'x'        ; which are not IBM ROM...
  2434.         jne  last_chk
  2435.         and  equ_flag,0h                 ; ... BIOS compatible. 
  2436.         or   inv_flag,0FFh
  2437.         or   drv_flag,0FFh
  2438.         or   mem_flag,0FFh
  2439.         or   argc,0FFh
  2440.         jmp  swt_char
  2441. last_chk:
  2442.         dec  bx
  2443.         jmp  swt_char
  2444. end_swt:
  2445.         cmp  argc,0FFh
  2446.         jne  not_all
  2447.         mov  optcnt,4
  2448. not_all:
  2449.         cmp  optcnt,1                    ; must specify one switch at least
  2450.         jnb  lv_swt
  2451.         mov  dx,offset usemsg
  2452.         call dostty
  2453.     mov  ax,4C01h                 ; Return code for abnormal completion
  2454.     int  21h             ; return to DOS
  2455. lv_swt:
  2456.         ret
  2457. chk_switch endp
  2458. ;
  2459. ;***********************************************************************
  2460. ;* Check the switch char for path names - is it "/" or "\"?
  2461. ;***********************************************************************
  2462. switch_char proc near
  2463.         mov  ax,3700h                    ; request switchar be returned in dl
  2464.         int  21h
  2465.         cmp  dl,5CH                      ; are they using "\" for switches?
  2466.         jne  not_unix_lover              ; no, "/" for switches, "\" for paths
  2467.         cmp  dl,2FH                      ; are they using "/" for switches?
  2468.         jne  func_not_working            ; if no, the function is not working
  2469.         mov  switchar,5Ch                ; change it around for unix lovers
  2470.         mov  pathchar,2Fh                ; least they be troubled... :-)
  2471.         jmp  func_works
  2472. not_unix_lover:
  2473.         cmp  dl,2FH                      ; are they using "/" for switches?
  2474.         je   func_works                  ; the undocumented function works
  2475. func_not_working:
  2476.         mov  al,0FFh                     ; if no, the function is not working
  2477.                                          ; leave defaults in place, signal err
  2478. func_works:
  2479.         ret
  2480. switch_char endp
  2481. ;
  2482. ;***********************************************************************
  2483. ;* Check to see if screen is full during MCB display.
  2484. ;***********************************************************************
  2485. chk_screen proc near
  2486.         push ax
  2487.         push dx
  2488.         xor  ax,ax
  2489.         mov  al,byte ptr linecnt
  2490.         add  al,one                      ; will be 0 if pause, 1 if not
  2491.         cmp  al,14h                      ; 20 lines per screen
  2492.         jb   not_full
  2493.     mov  dx,offset newline
  2494.         call dostty
  2495.     mov  dx,offset msg7         ; press any key message
  2496.         call dostty
  2497.     mov  ah,get_key                  ; function number (0h or 10h)
  2498.     int  16h                         ; ascii code for key pressed in ah
  2499.         xor  al,al
  2500. not_full:
  2501.         mov  byte ptr linecnt,al         ; store the updated counter
  2502.         pop  dx
  2503.         pop  ax
  2504.         ret
  2505. chk_screen endp
  2506. ;
  2507. cseg    ends
  2508.     end  begin
  2509. ;*****************************************************************************
  2510. ;* End Of Source Code.
  2511. ;*****************************************************************************
  2512.